@kontent-ai/delivery-sdk 16.4.3 → 16.4.5

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 (113) hide show
  1. package/.npmignore +15 -15
  2. package/LICENSE.md +9 -9
  3. package/dist/bundles/kontent-delivery.umd.js +5076 -4619
  4. package/dist/bundles/kontent-delivery.umd.js.map +1 -1
  5. package/dist/bundles/kontent-delivery.umd.min.js +1 -1
  6. package/dist/bundles/kontent-delivery.umd.min.js.map +1 -1
  7. package/dist/bundles/report.json +1 -1
  8. package/dist/bundles/report.min.json +1 -1
  9. package/dist/bundles/stats.json +7015 -5766
  10. package/dist/bundles/stats.min.json +11376 -10250
  11. package/dist/cjs/query/element/element-query.class.js +1 -1
  12. package/dist/cjs/query/element/element-query.class.js.map +1 -1
  13. package/dist/cjs/query/item/single-item-query.class.js +1 -1
  14. package/dist/cjs/query/item/single-item-query.class.js.map +1 -1
  15. package/dist/cjs/query/taxonomy/taxonomy-query.class.js +1 -1
  16. package/dist/cjs/query/taxonomy/taxonomy-query.class.js.map +1 -1
  17. package/dist/cjs/query/type/single-type-query.class.js +1 -1
  18. package/dist/cjs/query/type/single-type-query.class.js.map +1 -1
  19. package/dist/cjs/query/used-in/used-in-query.class.js +1 -1
  20. package/dist/cjs/query/used-in/used-in-query.class.js.map +1 -1
  21. package/dist/cjs/sdk-info.generated.js +1 -1
  22. package/dist/es6/query/element/element-query.class.js +1 -1
  23. package/dist/es6/query/element/element-query.class.js.map +1 -1
  24. package/dist/es6/query/item/single-item-query.class.js +1 -1
  25. package/dist/es6/query/item/single-item-query.class.js.map +1 -1
  26. package/dist/es6/query/taxonomy/taxonomy-query.class.js +1 -1
  27. package/dist/es6/query/taxonomy/taxonomy-query.class.js.map +1 -1
  28. package/dist/es6/query/type/single-type-query.class.js +1 -1
  29. package/dist/es6/query/type/single-type-query.class.js.map +1 -1
  30. package/dist/es6/query/used-in/used-in-query.class.js +1 -1
  31. package/dist/es6/query/used-in/used-in-query.class.js.map +1 -1
  32. package/dist/es6/sdk-info.generated.js +1 -1
  33. package/dist/esnext/query/element/element-query.class.js +1 -1
  34. package/dist/esnext/query/element/element-query.class.js.map +1 -1
  35. package/dist/esnext/query/item/single-item-query.class.js +1 -1
  36. package/dist/esnext/query/item/single-item-query.class.js.map +1 -1
  37. package/dist/esnext/query/taxonomy/taxonomy-query.class.js +1 -1
  38. package/dist/esnext/query/taxonomy/taxonomy-query.class.js.map +1 -1
  39. package/dist/esnext/query/type/single-type-query.class.js +1 -1
  40. package/dist/esnext/query/type/single-type-query.class.js.map +1 -1
  41. package/dist/esnext/query/used-in/used-in-query.class.js +1 -1
  42. package/dist/esnext/query/used-in/used-in-query.class.js.map +1 -1
  43. package/dist/esnext/sdk-info.generated.js +1 -1
  44. package/lib/client/delivery-client.factory.ts +9 -9
  45. package/lib/client/delivery-client.ts +163 -163
  46. package/lib/client/idelivery-client.interface.ts +110 -110
  47. package/lib/client/index.ts +3 -3
  48. package/lib/config/delivery-configs.ts +98 -98
  49. package/lib/config/index.ts +1 -1
  50. package/lib/contracts/contracts.ts +265 -265
  51. package/lib/contracts/index.ts +1 -1
  52. package/lib/elements/element-models.ts +89 -89
  53. package/lib/elements/element-resolver.ts +3 -3
  54. package/lib/elements/element-type.ts +16 -16
  55. package/lib/elements/elements.ts +70 -70
  56. package/lib/elements/index.ts +4 -4
  57. package/lib/images/image-url-transformation-builder.factory.ts +5 -5
  58. package/lib/images/image-url-transformation-builder.ts +181 -181
  59. package/lib/images/image.models.ts +4 -4
  60. package/lib/images/index.ts +3 -3
  61. package/lib/index.ts +12 -12
  62. package/lib/mappers/element.mapper.ts +504 -504
  63. package/lib/mappers/generic-element.mapper.ts +20 -20
  64. package/lib/mappers/index.ts +8 -8
  65. package/lib/mappers/item.mapper.ts +181 -181
  66. package/lib/mappers/language.mapper.ts +24 -24
  67. package/lib/mappers/sync.mapper.ts +32 -32
  68. package/lib/mappers/taxonomy.mapper.ts +77 -77
  69. package/lib/mappers/type.mapper.ts +76 -76
  70. package/lib/mappers/used-in.mapper.ts +20 -20
  71. package/lib/models/common/base-responses.ts +13 -13
  72. package/lib/models/common/common-models.ts +118 -118
  73. package/lib/models/common/filters.ts +280 -280
  74. package/lib/models/common/headers.ts +5 -5
  75. package/lib/models/common/index.ts +7 -7
  76. package/lib/models/common/pagination.class.ts +7 -7
  77. package/lib/models/common/parameters.ts +189 -189
  78. package/lib/models/common/sort-order.ts +1 -1
  79. package/lib/models/content-type-models.ts +42 -42
  80. package/lib/models/element-models.ts +51 -51
  81. package/lib/models/index.ts +9 -9
  82. package/lib/models/item-models.ts +192 -192
  83. package/lib/models/language-models.ts +17 -17
  84. package/lib/models/responses.ts +137 -137
  85. package/lib/models/sync-models.ts +18 -18
  86. package/lib/models/taxonomy-models.ts +25 -25
  87. package/lib/query/common/base-item-listing-query.class.ts +274 -274
  88. package/lib/query/common/base-listing-query.class.ts +95 -95
  89. package/lib/query/common/base-query.class.ts +148 -148
  90. package/lib/query/element/element-query.class.ts +47 -45
  91. package/lib/query/index.ts +13 -13
  92. package/lib/query/item/multiple-items-query.class.ts +183 -183
  93. package/lib/query/item/single-item-query.class.ts +106 -106
  94. package/lib/query/items-feed/items-feed-query.class.ts +191 -191
  95. package/lib/query/language/languages-query.class.ts +91 -91
  96. package/lib/query/sync/initialize-sync-query.class.ts +83 -83
  97. package/lib/query/sync/sync-changes-query.class.ts +56 -56
  98. package/lib/query/taxonomy/taxonomies-query.class.ts +82 -82
  99. package/lib/query/taxonomy/taxonomy-query.class.ts +50 -50
  100. package/lib/query/type/multiple-type-query.class.ts +95 -95
  101. package/lib/query/type/single-type-query.class.ts +45 -45
  102. package/lib/query/used-in/used-in-query.class.ts +128 -126
  103. package/lib/sdk-info.generated.ts +1 -1
  104. package/lib/services/base-delivery-query.service.ts +375 -375
  105. package/lib/services/delivery-query.service.ts +336 -336
  106. package/lib/services/index.ts +2 -2
  107. package/lib/services/mapping.service.ts +223 -223
  108. package/lib/utilities/codename.helper.ts +10 -10
  109. package/lib/utilities/delivery-url.helper.ts +11 -11
  110. package/lib/utilities/enum.helper.ts +38 -38
  111. package/lib/utilities/index.ts +3 -3
  112. package/package.json +96 -96
  113. package/readme.md +531 -531
@@ -1,375 +1,375 @@
1
- import { IResponse, IHeader, IHttpService, IQueryParameter, urlHelper } from '@kontent-ai/core-sdk';
2
- import { AxiosError } from 'axios';
3
- import {
4
- waitForLoadingNewContentHeader,
5
- IQueryConfig,
6
- ISDKInfo,
7
- IDeliveryErrorRaw,
8
- DeliveryError,
9
- sdkVersionHeader,
10
- staleContentHeaderName,
11
- continuationTokenHeaderName,
12
- IDeliveryNetworkResponse,
13
- ClientTypes
14
- } from '../models';
15
-
16
- import { IDeliveryClientConfig } from '../config';
17
- import { IMappingService } from './mapping.service';
18
-
19
- export abstract class BaseDeliveryQueryService<TClientTypes extends ClientTypes> {
20
- /**
21
- * Default base Url to Kontent.ai Delivery API
22
- */
23
- private readonly defaultBaseDeliveryApiUrl: string = 'https://deliver.kontent.ai';
24
-
25
- /**
26
- * Default preview url to Kontent.ai Delivery API
27
- */
28
- private readonly defaultPreviewDeliveryApiUrl: string = 'https://preview-deliver.kontent.ai';
29
-
30
- constructor(
31
- /**
32
- * Delivery client configuration
33
- */
34
- public readonly config: IDeliveryClientConfig,
35
- /**
36
- * Http service for fetching data
37
- */
38
- public readonly httpService: IHttpService<any>,
39
- /**
40
- * Information about the SDK
41
- */
42
- public readonly sdkInfo: ISDKInfo,
43
- /**
44
- * Mapping service
45
- */
46
- public readonly mappingService: IMappingService<TClientTypes>
47
- ) {}
48
-
49
- /**
50
- * Gets url based on the action, query configuration and options (parameters)
51
- * @param action Action (= url part) that will be hit
52
- * @param queryConfig Query configuration
53
- * @param options Query options
54
- */
55
- getUrl(action: string, queryConfig: IQueryConfig, options?: IQueryParameter[]): string {
56
- if (!this.config.proxy || !this.config.proxy.advancedProxyUrlResolver) {
57
- return urlHelper.addOptionsToUrl(this.getBaseUrl(queryConfig) + action, options);
58
- }
59
- return this.config.proxy.advancedProxyUrlResolver({
60
- queryParameters: options ? options : [],
61
- queryString: urlHelper.addOptionsToUrl('', options),
62
- action: action,
63
- domain: this.getDomain(queryConfig),
64
- queryConfig: queryConfig,
65
- environmentId: this.config.environmentId
66
- });
67
- }
68
-
69
- /**
70
- * Gets proper set of headers for given request.
71
- * @param queryConfig Query configuration
72
- * @param additionalHeaders Custom headers
73
- */
74
- getHeaders(queryConfig: IQueryConfig, additionalHeaders?: IHeader[]): IHeader[] {
75
- const headers: IHeader[] = [];
76
-
77
- if (additionalHeaders) {
78
- headers.push(...additionalHeaders);
79
- }
80
-
81
- // add SDK Id header for monitoring SDK usage
82
- headers.push(this.getSdkIdHeader());
83
-
84
- // add headers from global config
85
- if (this.config.globalHeaders) {
86
- headers.push(...this.config.globalHeaders(queryConfig));
87
- }
88
-
89
- // add query / global headers from query config
90
- headers.push(...this.getQueryHeaders(queryConfig));
91
-
92
- if (this.isPreviewModeEnabled(queryConfig) && this.isSecuredModeEnabled(queryConfig)) {
93
- throw Error(`Preview & secured modes cannot be used at the same time.`);
94
- }
95
-
96
- // add preview header is required
97
- if (this.isPreviewModeEnabled(queryConfig) && this.config.previewApiKey) {
98
- headers.push(this.getAuthorizationHeader(this.config.previewApiKey));
99
- }
100
-
101
- // add secured mode header is required
102
- if (this.isSecuredModeEnabled(queryConfig) && this.config.secureApiKey) {
103
- headers.push(this.getAuthorizationHeader(this.config.secureApiKey));
104
- }
105
-
106
- // add 'X-KC-Wait-For-Loading-New-Content' header if required
107
- if (this.shouldAddWaitForLoadingNewContentHeader(queryConfig)) {
108
- headers.push({
109
- header: waitForLoadingNewContentHeader,
110
- value: 'true'
111
- });
112
- }
113
-
114
- return headers;
115
- }
116
-
117
- /**
118
- * Http POST response
119
- * @param url Url of request
120
- * @param queryConfig Query config configuration
121
- */
122
- protected async postResponseAsync<TRawData>(
123
- url: string,
124
- body: any,
125
- queryConfig?: IQueryConfig,
126
- serviceConfig?: {
127
- headers?: IHeader[];
128
- }
129
- ): Promise<IResponse<TRawData>> {
130
- if (!queryConfig) {
131
- queryConfig = {};
132
- }
133
-
134
- if (!serviceConfig) {
135
- serviceConfig = {};
136
- }
137
-
138
- try {
139
- return await this.httpService.postAsync<TRawData>(
140
- {
141
- url: url,
142
- body: body
143
- },
144
- {
145
- cancelToken: queryConfig?.cancelToken,
146
- responseType: 'json',
147
- retryStrategy: this.config.retryStrategy,
148
- headers: this.getHeaders(queryConfig, serviceConfig.headers ? serviceConfig.headers : [])
149
- }
150
- );
151
- } catch (error) {
152
- throw this.mapDeliveryError(error);
153
- }
154
- }
155
-
156
- /**
157
- * Http GET response
158
- * @param url Url of request
159
- * @param queryConfig Query config configuration
160
- */
161
- protected async getResponseAsync<TRawData>(
162
- url: string,
163
- queryConfig?: IQueryConfig,
164
- serviceConfig?: {
165
- headers?: IHeader[];
166
- }
167
- ): Promise<IResponse<TRawData>> {
168
- if (!queryConfig) {
169
- queryConfig = {};
170
- }
171
-
172
- if (!serviceConfig) {
173
- serviceConfig = {};
174
- }
175
-
176
- try {
177
- return await this.httpService.getAsync<TRawData>(
178
- {
179
- url: url
180
- },
181
- {
182
- cancelToken: queryConfig?.cancelToken,
183
- responseType: 'json',
184
- retryStrategy: this.config.retryStrategy,
185
- headers: this.getHeaders(queryConfig, serviceConfig.headers ? serviceConfig.headers : [])
186
- }
187
- );
188
- } catch (error) {
189
- throw this.mapDeliveryError(error);
190
- }
191
- }
192
-
193
- /**
194
- * Gets base URL of the request including the environment Id
195
- * @param queryConfig Query configuration
196
- */
197
- protected getBaseUrl(queryConfig: IQueryConfig): string {
198
- return this.getDomain(queryConfig) + '/' + this.config.environmentId;
199
- }
200
-
201
- protected mapNetworkResponse<TData, TContract>(
202
- data: TData,
203
- response: IResponse<any>
204
- ): IDeliveryNetworkResponse<TData, TContract> {
205
- return {
206
- data: data,
207
- response: response,
208
- hasStaleContent: this.getHasStaleContent(response.headers),
209
- xContinuationToken: this.getContinuationToken(response.headers)
210
- };
211
- }
212
-
213
- /**
214
- * Indicates if current query should use preview mode
215
- * @param queryConfig Query configuration
216
- */
217
- private isPreviewModeEnabled(queryConfig: IQueryConfig): boolean {
218
- if (queryConfig.usePreviewMode !== undefined) {
219
- return queryConfig.usePreviewMode;
220
- }
221
-
222
- if (!this.config.defaultQueryConfig) {
223
- return false;
224
- }
225
-
226
- if (this.config.defaultQueryConfig.usePreviewMode === true) {
227
- return true;
228
- }
229
-
230
- return false;
231
- }
232
-
233
- private getQueryHeaders(queryConfig: IQueryConfig): IHeader[] {
234
- if (queryConfig.customHeaders) {
235
- return queryConfig.customHeaders;
236
- }
237
-
238
- if (this.config.defaultQueryConfig?.customHeaders) {
239
- return this.config.defaultQueryConfig.customHeaders;
240
- }
241
-
242
- return [];
243
- }
244
-
245
- private shouldAddWaitForLoadingNewContentHeader(queryConfig: IQueryConfig): boolean {
246
- if (queryConfig.waitForLoadingNewContent !== undefined) {
247
- return queryConfig.waitForLoadingNewContent;
248
- }
249
-
250
- if (!this.config.defaultQueryConfig) {
251
- return false;
252
- }
253
-
254
- if (this.config.defaultQueryConfig.waitForLoadingNewContent === true) {
255
- return true;
256
- }
257
-
258
- return false;
259
- }
260
-
261
- /**
262
- * Indicates if current query should use secured mode
263
- * @param queryConfig Query configuration
264
- */
265
- private isSecuredModeEnabled(queryConfig: IQueryConfig): boolean {
266
- if (queryConfig.useSecuredMode !== undefined) {
267
- return queryConfig.useSecuredMode;
268
- }
269
-
270
- if (!this.config.defaultQueryConfig) {
271
- return false;
272
- }
273
-
274
- if (this.config.defaultQueryConfig.useSecuredMode === true) {
275
- return true;
276
- }
277
-
278
- return false;
279
- }
280
-
281
- /**
282
- * Gets preview or standard URL based on client and query configuration
283
- * @param queryConfig Query configuration
284
- */
285
- private getDomain(queryConfig: IQueryConfig): string {
286
- if (this.isPreviewModeEnabled(queryConfig)) {
287
- if (!this.config.previewApiKey) {
288
- throw Error(`Preview API key is not configured.`);
289
- }
290
-
291
- // check custom preview url
292
- if (this.config.proxy && this.config.proxy.basePreviewUrl) {
293
- return this.config.proxy.basePreviewUrl;
294
- }
295
-
296
- // use default preview url
297
- return this.defaultPreviewDeliveryApiUrl;
298
- }
299
-
300
- // check custom base url
301
- if (this.config.proxy && this.config.proxy.baseUrl) {
302
- return this.config.proxy.baseUrl;
303
- }
304
- return this.defaultBaseDeliveryApiUrl;
305
- }
306
-
307
- /**
308
- * Gets authorization header. This is used for 'preview' functionality
309
- */
310
- private getAuthorizationHeader(key?: string): IHeader {
311
- if (!key) {
312
- throw Error(`Cannot get authorization header because key is invalid`);
313
- }
314
- // authorization header required for preview mode
315
- return {
316
- header: 'authorization',
317
- value: `bearer ${key}`
318
- };
319
- }
320
-
321
- /**
322
- * Header identifying SDK type & version for internal purposes of Kontent.ai
323
- */
324
- private getSdkIdHeader(): IHeader {
325
- return {
326
- header: sdkVersionHeader,
327
- value: `${this.sdkInfo.host};${this.sdkInfo.name};${this.sdkInfo.version}`
328
- };
329
- }
330
-
331
- private mapDeliveryError(error: any): any {
332
- let axiosError: AxiosError | undefined;
333
-
334
- if (error.error) {
335
- axiosError = error.error;
336
- } else {
337
- axiosError = error;
338
- }
339
-
340
- if (!axiosError || !axiosError.isAxiosError) {
341
- return error;
342
- }
343
-
344
- const deliveryErrorData = axiosError.response?.data as IDeliveryErrorRaw;
345
-
346
- if (!deliveryErrorData || !deliveryErrorData.error_code) {
347
- return error;
348
- }
349
-
350
- return new DeliveryError({
351
- errorCode: deliveryErrorData.error_code,
352
- message: deliveryErrorData.message,
353
- specificCode: deliveryErrorData.specific_code,
354
- requestId: deliveryErrorData.request_id
355
- });
356
- }
357
-
358
- private getHasStaleContent(headers: IHeader[]): boolean {
359
- const hasStaleContentHeader = headers.find(
360
- (m) => m.header.toLowerCase() === staleContentHeaderName.toLowerCase()
361
- );
362
-
363
- if (hasStaleContentHeader) {
364
- if (hasStaleContentHeader.value.toString() === '1') {
365
- return true;
366
- }
367
- }
368
- return false;
369
- }
370
-
371
- private getContinuationToken(headers: IHeader[]): string | undefined {
372
- const header = headers.find((m) => m.header.toLowerCase() === continuationTokenHeaderName.toLowerCase());
373
- return header ? header.value : undefined;
374
- }
375
- }
1
+ import { IResponse, IHeader, IHttpService, IQueryParameter, urlHelper } from '@kontent-ai/core-sdk';
2
+ import { AxiosError } from 'axios';
3
+ import {
4
+ waitForLoadingNewContentHeader,
5
+ IQueryConfig,
6
+ ISDKInfo,
7
+ IDeliveryErrorRaw,
8
+ DeliveryError,
9
+ sdkVersionHeader,
10
+ staleContentHeaderName,
11
+ continuationTokenHeaderName,
12
+ IDeliveryNetworkResponse,
13
+ ClientTypes
14
+ } from '../models';
15
+
16
+ import { IDeliveryClientConfig } from '../config';
17
+ import { IMappingService } from './mapping.service';
18
+
19
+ export abstract class BaseDeliveryQueryService<TClientTypes extends ClientTypes> {
20
+ /**
21
+ * Default base Url to Kontent.ai Delivery API
22
+ */
23
+ private readonly defaultBaseDeliveryApiUrl: string = 'https://deliver.kontent.ai';
24
+
25
+ /**
26
+ * Default preview url to Kontent.ai Delivery API
27
+ */
28
+ private readonly defaultPreviewDeliveryApiUrl: string = 'https://preview-deliver.kontent.ai';
29
+
30
+ constructor(
31
+ /**
32
+ * Delivery client configuration
33
+ */
34
+ public readonly config: IDeliveryClientConfig,
35
+ /**
36
+ * Http service for fetching data
37
+ */
38
+ public readonly httpService: IHttpService<any>,
39
+ /**
40
+ * Information about the SDK
41
+ */
42
+ public readonly sdkInfo: ISDKInfo,
43
+ /**
44
+ * Mapping service
45
+ */
46
+ public readonly mappingService: IMappingService<TClientTypes>
47
+ ) {}
48
+
49
+ /**
50
+ * Gets url based on the action, query configuration and options (parameters)
51
+ * @param action Action (= url part) that will be hit
52
+ * @param queryConfig Query configuration
53
+ * @param options Query options
54
+ */
55
+ getUrl(action: string, queryConfig: IQueryConfig, options?: IQueryParameter[]): string {
56
+ if (!this.config.proxy || !this.config.proxy.advancedProxyUrlResolver) {
57
+ return urlHelper.addOptionsToUrl(this.getBaseUrl(queryConfig) + action, options);
58
+ }
59
+ return this.config.proxy.advancedProxyUrlResolver({
60
+ queryParameters: options ? options : [],
61
+ queryString: urlHelper.addOptionsToUrl('', options),
62
+ action: action,
63
+ domain: this.getDomain(queryConfig),
64
+ queryConfig: queryConfig,
65
+ environmentId: this.config.environmentId
66
+ });
67
+ }
68
+
69
+ /**
70
+ * Gets proper set of headers for given request.
71
+ * @param queryConfig Query configuration
72
+ * @param additionalHeaders Custom headers
73
+ */
74
+ getHeaders(queryConfig: IQueryConfig, additionalHeaders?: IHeader[]): IHeader[] {
75
+ const headers: IHeader[] = [];
76
+
77
+ if (additionalHeaders) {
78
+ headers.push(...additionalHeaders);
79
+ }
80
+
81
+ // add SDK Id header for monitoring SDK usage
82
+ headers.push(this.getSdkIdHeader());
83
+
84
+ // add headers from global config
85
+ if (this.config.globalHeaders) {
86
+ headers.push(...this.config.globalHeaders(queryConfig));
87
+ }
88
+
89
+ // add query / global headers from query config
90
+ headers.push(...this.getQueryHeaders(queryConfig));
91
+
92
+ if (this.isPreviewModeEnabled(queryConfig) && this.isSecuredModeEnabled(queryConfig)) {
93
+ throw Error(`Preview & secured modes cannot be used at the same time.`);
94
+ }
95
+
96
+ // add preview header is required
97
+ if (this.isPreviewModeEnabled(queryConfig) && this.config.previewApiKey) {
98
+ headers.push(this.getAuthorizationHeader(this.config.previewApiKey));
99
+ }
100
+
101
+ // add secured mode header is required
102
+ if (this.isSecuredModeEnabled(queryConfig) && this.config.secureApiKey) {
103
+ headers.push(this.getAuthorizationHeader(this.config.secureApiKey));
104
+ }
105
+
106
+ // add 'X-KC-Wait-For-Loading-New-Content' header if required
107
+ if (this.shouldAddWaitForLoadingNewContentHeader(queryConfig)) {
108
+ headers.push({
109
+ header: waitForLoadingNewContentHeader,
110
+ value: 'true'
111
+ });
112
+ }
113
+
114
+ return headers;
115
+ }
116
+
117
+ /**
118
+ * Http POST response
119
+ * @param url Url of request
120
+ * @param queryConfig Query config configuration
121
+ */
122
+ protected async postResponseAsync<TRawData>(
123
+ url: string,
124
+ body: any,
125
+ queryConfig?: IQueryConfig,
126
+ serviceConfig?: {
127
+ headers?: IHeader[];
128
+ }
129
+ ): Promise<IResponse<TRawData>> {
130
+ if (!queryConfig) {
131
+ queryConfig = {};
132
+ }
133
+
134
+ if (!serviceConfig) {
135
+ serviceConfig = {};
136
+ }
137
+
138
+ try {
139
+ return await this.httpService.postAsync<TRawData>(
140
+ {
141
+ url: url,
142
+ body: body
143
+ },
144
+ {
145
+ cancelToken: queryConfig?.cancelToken,
146
+ responseType: 'json',
147
+ retryStrategy: this.config.retryStrategy,
148
+ headers: this.getHeaders(queryConfig, serviceConfig.headers ? serviceConfig.headers : [])
149
+ }
150
+ );
151
+ } catch (error) {
152
+ throw this.mapDeliveryError(error);
153
+ }
154
+ }
155
+
156
+ /**
157
+ * Http GET response
158
+ * @param url Url of request
159
+ * @param queryConfig Query config configuration
160
+ */
161
+ protected async getResponseAsync<TRawData>(
162
+ url: string,
163
+ queryConfig?: IQueryConfig,
164
+ serviceConfig?: {
165
+ headers?: IHeader[];
166
+ }
167
+ ): Promise<IResponse<TRawData>> {
168
+ if (!queryConfig) {
169
+ queryConfig = {};
170
+ }
171
+
172
+ if (!serviceConfig) {
173
+ serviceConfig = {};
174
+ }
175
+
176
+ try {
177
+ return await this.httpService.getAsync<TRawData>(
178
+ {
179
+ url: url
180
+ },
181
+ {
182
+ cancelToken: queryConfig?.cancelToken,
183
+ responseType: 'json',
184
+ retryStrategy: this.config.retryStrategy,
185
+ headers: this.getHeaders(queryConfig, serviceConfig.headers ? serviceConfig.headers : [])
186
+ }
187
+ );
188
+ } catch (error) {
189
+ throw this.mapDeliveryError(error);
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Gets base URL of the request including the environment Id
195
+ * @param queryConfig Query configuration
196
+ */
197
+ protected getBaseUrl(queryConfig: IQueryConfig): string {
198
+ return this.getDomain(queryConfig) + '/' + this.config.environmentId;
199
+ }
200
+
201
+ protected mapNetworkResponse<TData, TContract>(
202
+ data: TData,
203
+ response: IResponse<any>
204
+ ): IDeliveryNetworkResponse<TData, TContract> {
205
+ return {
206
+ data: data,
207
+ response: response,
208
+ hasStaleContent: this.getHasStaleContent(response.headers),
209
+ xContinuationToken: this.getContinuationToken(response.headers)
210
+ };
211
+ }
212
+
213
+ /**
214
+ * Indicates if current query should use preview mode
215
+ * @param queryConfig Query configuration
216
+ */
217
+ private isPreviewModeEnabled(queryConfig: IQueryConfig): boolean {
218
+ if (queryConfig.usePreviewMode !== undefined) {
219
+ return queryConfig.usePreviewMode;
220
+ }
221
+
222
+ if (!this.config.defaultQueryConfig) {
223
+ return false;
224
+ }
225
+
226
+ if (this.config.defaultQueryConfig.usePreviewMode === true) {
227
+ return true;
228
+ }
229
+
230
+ return false;
231
+ }
232
+
233
+ private getQueryHeaders(queryConfig: IQueryConfig): IHeader[] {
234
+ if (queryConfig.customHeaders) {
235
+ return queryConfig.customHeaders;
236
+ }
237
+
238
+ if (this.config.defaultQueryConfig?.customHeaders) {
239
+ return this.config.defaultQueryConfig.customHeaders;
240
+ }
241
+
242
+ return [];
243
+ }
244
+
245
+ private shouldAddWaitForLoadingNewContentHeader(queryConfig: IQueryConfig): boolean {
246
+ if (queryConfig.waitForLoadingNewContent !== undefined) {
247
+ return queryConfig.waitForLoadingNewContent;
248
+ }
249
+
250
+ if (!this.config.defaultQueryConfig) {
251
+ return false;
252
+ }
253
+
254
+ if (this.config.defaultQueryConfig.waitForLoadingNewContent === true) {
255
+ return true;
256
+ }
257
+
258
+ return false;
259
+ }
260
+
261
+ /**
262
+ * Indicates if current query should use secured mode
263
+ * @param queryConfig Query configuration
264
+ */
265
+ private isSecuredModeEnabled(queryConfig: IQueryConfig): boolean {
266
+ if (queryConfig.useSecuredMode !== undefined) {
267
+ return queryConfig.useSecuredMode;
268
+ }
269
+
270
+ if (!this.config.defaultQueryConfig) {
271
+ return false;
272
+ }
273
+
274
+ if (this.config.defaultQueryConfig.useSecuredMode === true) {
275
+ return true;
276
+ }
277
+
278
+ return false;
279
+ }
280
+
281
+ /**
282
+ * Gets preview or standard URL based on client and query configuration
283
+ * @param queryConfig Query configuration
284
+ */
285
+ private getDomain(queryConfig: IQueryConfig): string {
286
+ if (this.isPreviewModeEnabled(queryConfig)) {
287
+ if (!this.config.previewApiKey) {
288
+ throw Error(`Preview API key is not configured.`);
289
+ }
290
+
291
+ // check custom preview url
292
+ if (this.config.proxy && this.config.proxy.basePreviewUrl) {
293
+ return this.config.proxy.basePreviewUrl;
294
+ }
295
+
296
+ // use default preview url
297
+ return this.defaultPreviewDeliveryApiUrl;
298
+ }
299
+
300
+ // check custom base url
301
+ if (this.config.proxy && this.config.proxy.baseUrl) {
302
+ return this.config.proxy.baseUrl;
303
+ }
304
+ return this.defaultBaseDeliveryApiUrl;
305
+ }
306
+
307
+ /**
308
+ * Gets authorization header. This is used for 'preview' functionality
309
+ */
310
+ private getAuthorizationHeader(key?: string): IHeader {
311
+ if (!key) {
312
+ throw Error(`Cannot get authorization header because key is invalid`);
313
+ }
314
+ // authorization header required for preview mode
315
+ return {
316
+ header: 'authorization',
317
+ value: `bearer ${key}`
318
+ };
319
+ }
320
+
321
+ /**
322
+ * Header identifying SDK type & version for internal purposes of Kontent.ai
323
+ */
324
+ private getSdkIdHeader(): IHeader {
325
+ return {
326
+ header: sdkVersionHeader,
327
+ value: `${this.sdkInfo.host};${this.sdkInfo.name};${this.sdkInfo.version}`
328
+ };
329
+ }
330
+
331
+ private mapDeliveryError(error: any): any {
332
+ let axiosError: AxiosError | undefined;
333
+
334
+ if (error.error) {
335
+ axiosError = error.error;
336
+ } else {
337
+ axiosError = error;
338
+ }
339
+
340
+ if (!axiosError || !axiosError.isAxiosError) {
341
+ return error;
342
+ }
343
+
344
+ const deliveryErrorData = axiosError.response?.data as IDeliveryErrorRaw;
345
+
346
+ if (!deliveryErrorData || !deliveryErrorData.error_code) {
347
+ return error;
348
+ }
349
+
350
+ return new DeliveryError({
351
+ errorCode: deliveryErrorData.error_code,
352
+ message: deliveryErrorData.message,
353
+ specificCode: deliveryErrorData.specific_code,
354
+ requestId: deliveryErrorData.request_id
355
+ });
356
+ }
357
+
358
+ private getHasStaleContent(headers: IHeader[]): boolean {
359
+ const hasStaleContentHeader = headers.find(
360
+ (m) => m.header.toLowerCase() === staleContentHeaderName.toLowerCase()
361
+ );
362
+
363
+ if (hasStaleContentHeader) {
364
+ if (hasStaleContentHeader.value.toString() === '1') {
365
+ return true;
366
+ }
367
+ }
368
+ return false;
369
+ }
370
+
371
+ private getContinuationToken(headers: IHeader[]): string | undefined {
372
+ const header = headers.find((m) => m.header.toLowerCase() === continuationTokenHeaderName.toLowerCase());
373
+ return header ? header.value : undefined;
374
+ }
375
+ }