@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
package/readme.md CHANGED
@@ -1,531 +1,531 @@
1
- [![npm version](https://badge.fury.io/js/%40kontent-ai%2Fdelivery-sdk.svg)](https://badge.fury.io/js/%40kontent-ai%2Fdelivery-sdk)
2
- [![Build](https://github.com/kontent-ai/delivery-sdk-js/actions/workflows/test.yml/badge.svg)](https://github.com/kontent-ai/delivery-sdk-js/actions/workflows/test.yml)
3
- [![npm](https://img.shields.io/npm/dt/@kontent-ai/delivery-sdk.svg)](https://www.npmjs.com/package/@kontent-ai/delivery-sdk)
4
- [![Known Vulnerabilities](https://snyk.io/test/github/kontent-ai/delivery-sdk-js/badge.svg)](https://snyk.io/test/github/kontent-ai/delivery-sdk-js)
5
- [![GitHub license](https://img.shields.io/github/license/kontent-ai/delivery-sdk-js.svg)](https://github.com/kontent-ai/delivery-sdk-js)
6
- ![Gzip browser bundle](https://img.badgesize.io/https:/cdn.jsdelivr.net/npm/@kontent-ai/delivery-sdk/dist/bundles/kontent-delivery.umd.min.js?compression=gzip)
7
- [![Discord](https://img.shields.io/discord/821885171984891914?label=Discord&logo=Discord&logoColor=white)](https://discord.gg/SKCxwPtevJ)
8
-
9
- # JavaScript Delivery SDK Documentation
10
-
11
- This library is build for fetching [Kontent.ai](https://kontent.ai/) data with `Delivery API`. Works in browser & node.
12
-
13
- > [!TIP]
14
- > It's **highly recommended** to use this library in combination with
15
- > [Model Generator](https://www.npmjs.com/package/@kontent-ai/model-generator). Generating models will greatly increase
16
- > type safety of your code and offer you an advanced intellisense.
17
-
18
- # Kontent.ai Delivery SDK
19
-
20
- ## Installation
21
-
22
- ```bash
23
- npm i @kontent-ai/delivery-sdk --save
24
- ```
25
-
26
- ## Getting started
27
-
28
- ```typescript
29
- import { type IContentItem, type Elements, createDeliveryClient } from '@kontent-ai/delivery-sdk';
30
-
31
- /**
32
- * Generate models with @kontent-ai/model-generator
33
- */
34
- export type Movie = IContentItem<{
35
- readonly title: Elements.TextElement;
36
- readonly plot: Elements.RichTextElement;
37
- readonly released: Elements.DateTimeElement;
38
- readonly length: Elements.NumberElement;
39
- readonly poster: Elements.AssetsElement;
40
- readonly category: Elements.MultipleChoiceElement;
41
- readonly stars: Elements.LinkedItemsElement<Actor>;
42
- readonly seoname: Elements.UrlSlugElement;
43
- readonly releasecategory: Elements.TaxonomyElement;
44
- }>;
45
-
46
- // Both `CoreDeliveryClient` and `CoreClientTypes` are types generated by @kontent-ai/model-generator
47
- // By using the generated types you will get access to advanced intellisense & type safety
48
- const deliveryClient: CoreDeliveryClient = createDeliveryClient<CoreClientTypes>({
49
- environmentId: '<YOUR_ENVIRONMENT_ID>'
50
- });
51
-
52
- // fetch items
53
- const response = await deliveryClient.items<Movie>().type('<CONTENT_TYPE_CODENAME>').toPromise();
54
-
55
- // read data of first item
56
- const movieText = response.data.items[0].elements.title.value;
57
- ```
58
-
59
- ## Configuration
60
-
61
- | Property | type | description |
62
- | ---------------------------- | :--------------------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
63
- | environmentId | string | environmentId of your Kontent.ai project |
64
- | elementResolver? | ElementResolver | Element resolver used to map custom elements |
65
- | previewApiKey? | string | Preview API key used to get unpublished content items |
66
- | defaultLanguage? | string | Sets default language that will be used for all queries unless overridden with query parameters |
67
- | proxy? | IDeliveryClientProxyConfig | Can be used to configure custom URLs. Useful when you use reverse proxy or have a need to transform URL - e.g. to remove 'environmentId' |
68
- | secureApiKey? | string | Secured API key: Use secured API only when running on Node.JS server, otherwise you can expose your key |
69
- | defaultQueryConfig? | IQueryConfig | Default configuration for all queries. Can be overridden by individual queries |
70
- | httpService ? | IHttpService | Can be used to inject custom http service for performing requests |
71
- | globalHeaders? | (queryConfig: IQueryConfig) => IHeader[] | Adds ability to add extra headers to each http request |
72
- | retryStrategy? | IRetryStrategyOptions | Retry strategy configuration |
73
- | linkedItemsReferenceHandler? | LinkedItemsReferenceHandler | Indicates if content items are automatically mapped. Available values: 'map' or 'ignore' |
74
- | assetsDomain? | string | Custom domain for assets. Changes url of assets in both asset & rich text elements |
75
- | defaultRenditionPreset? | string | Codename of rendition preset to be applied by default to the base asset URL path when present. When set, the SDK will provide the URL of customized images by default. Right now the only supported preset codename is `default`. |
76
- | excludeArchivedItems? | boolean | Can be used to exclude archived items from all queries by default. Only applicable when preview API is used. |
77
-
78
- ### Querying
79
-
80
- The SDK supports the following query parameters: `depthParameter`, `elementsParameter`, `excludeElementsParameter`,
81
- `limitParameter`, `orderParameter`, `skipParameter` and `languageParameter`. For more information about the parameters,
82
- see the [SDK query methods](#filter-content) below. You can also head over to
83
- [Delivery API reference](https://kontent.ai/learn/docs/apis/openapi/delivery-api/#tag/Filtering-parameters).
84
-
85
- ```typescript
86
- // Gets 5 items based on the Movie type
87
- deliveryClient.items<Movie>().type('movie').limitParameter(5).skipParameter(2).toPromise();
88
- ```
89
-
90
- | Filter |
91
- | -------------------------- |
92
- | `depthParameter` |
93
- | `elementsParameter` |
94
- | `excludeElementsParameter` |
95
- | `limitParameter` |
96
- | `orderParameter` |
97
- | `skipParameter` |
98
- | `languageParameter` |
99
-
100
- #### Filtering
101
-
102
- Filters are also considered query parameters and can be combined. See
103
- [Content filtering in API reference](https://kontent.ai/learn/docs/apis/openapi/delivery-api/#tag/Filtering-parameters)
104
- for more examples.
105
-
106
- ```typescript
107
- // Gets items based on the Movie type with 'Warrior' in their 'Title' element
108
- deliveryClient.items<Movie>().type('movie').equalsFilter('elements.title', 'Warrior').toPromise();
109
- ```
110
-
111
- | Filter |
112
- | -------------------------- |
113
- | `type` |
114
- | `types` |
115
- | `allFilter` |
116
- | `anyFilter` |
117
- | `containsFilter` |
118
- | `equalsFilter` |
119
- | `greaterThanFilter` |
120
- | `greaterThanOrEqualFilter` |
121
- | `inFilter` |
122
- | `lessThanFilter` |
123
- | `lessThanOrEqualFilter` |
124
- | `rangeFilter` |
125
- | `emptyFilter` |
126
- | `NotEmptyFilter` |
127
- | `notEqualsFilter` |
128
- | `notInFilter` |
129
-
130
- #### Soring
131
-
132
- You can sort data by using any of the following methods:
133
-
134
- ```typescript
135
- deliveryClient.items<Movie>().type('movie').orderByDescending('elements.title').toPromise();
136
- deliveryClient.items<Movie>().type('movie').orderByAscending('elements.title').toPromise();
137
- deliveryClient.items<Movie>().type('movie').orderParameter('elements.title', 'desc').toPromise();
138
- ```
139
-
140
- ### Execute queries with a custom URL
141
-
142
- When you have an URL (i.e. for `next page` in paging, for testing purposes or just if you prefer to build it on your
143
- own) and still want to leverage SDK functionality such as type mapping, property resolving etc., use `withUrl` parameter
144
- on any query such as:
145
-
146
- ```typescript
147
- deliveryClient
148
- .items<Movie>()
149
- .withUrl('https://deliver.kontent.ai/da5abe9f-fdad-4168-97cd-b3464be2ccb9/items?system.type=movie')
150
- .toPromise();
151
- ```
152
-
153
- ### Custom parameters
154
-
155
- In case you need to use custom parameters to build up an URL, use `withParameter` method:
156
-
157
- ```typescript
158
- deliveryClient.items<Movie>().withParameter('name', 'value').toPromise();
159
- ```
160
-
161
- ### Get localized items
162
-
163
- You can specify [language of items](https://kontent.ai/learn/tutorials/manage-kontent/projects/set-up-languages) with
164
- `languageParameter` of a particular query. You can also define default language that will be used if `languageParameter`
165
- is not used during the initialization of delivery client.
166
-
167
- ```typescript
168
- import { createDeliveryClient } from '@kontent-ai/delivery-sdk';
169
-
170
- var deliveryClient = new createDeliveryClient({
171
- environmentId: '<YOUR_ENVIRONMENT_ID>',
172
- defaultLanguage: 'es'
173
- });
174
-
175
- // Gets items in 'es' language because it is marked as default
176
- deliveryClient.item('warrior').toPromise();
177
-
178
- // Gets items in 'en' language because language parameter has priority over the default one
179
- deliveryClient.item('warrior').languageParameter(`en`).toPromise();
180
- ```
181
-
182
- ### Preview mode
183
-
184
- You can enable the preview mode either globally (when [initializing the DeliveryClient](#how-to-use-deliveryclient)) or
185
- per query. In each case, you need to set `previewApiKey` in the delivery client global configuration.
186
-
187
- #### Enable preview mode globally
188
-
189
- ```typescript
190
- import { createDeliveryClient } from '@kontent-ai/delivery-sdk';
191
-
192
- const deliveryClient = createDeliveryClient({
193
- environmentId: '<YOUR_ENVIRONMENT_ID>';
194
- previewApiKey: '<YOUR_PREVIEW_API_KEY>',
195
- defaultQueryConfig: {
196
- usePreviewMode: true
197
- }
198
- });
199
- ```
200
-
201
- #### Enable preview mode per query
202
-
203
- ```typescript
204
- deliveryClient
205
- .items()
206
- .queryConfig({
207
- usePreviewMode: true
208
- })
209
- .toPromise();
210
- ```
211
-
212
- ### Secure Delivery API
213
-
214
- Using the Delivery API with
215
- [secure access](https://kontent.ai/learn/tutorials/develop-apps/build-strong-foundation/restrict-public-access) enabled
216
- is recommend only when the request is not being executed on the client (browser) because otherwise you will expose the
217
- API key publicly.
218
-
219
- ```typescript
220
- import { createDeliveryClient } from '@kontent-ai/delivery-sdk';
221
-
222
- const deliveryClient = createDeliveryClient({
223
- environmentId: '<YOUR_ENVIRONMENT_ID>';
224
- secureApiKey: '<YOUR_SECURE_ACCESS_KEY>',
225
- defaultQueryConfig: {
226
- // Enabled secure access for all queries
227
- useSecuredMode: true
228
- }
229
- });
230
- ```
231
-
232
- As with [preview mode](#preview-mode), you can also override global settings on query level.
233
-
234
- ```typescript
235
- deliveryClient
236
- .items()
237
- .queryConfig({
238
- // Enables secure access only for this query
239
- useSecuredMode: true
240
- })
241
- .toPromise();
242
- ```
243
-
244
- ### Image transformation
245
-
246
- Use `ImageUrlBuilder` for your [image transformations](https://kontent.ai/learn/reference/image-transformation) on asset
247
- URLs.
248
-
249
- ```typescript
250
- import { transformImageUrl } from '@kontent-ai/delivery-sdk';
251
-
252
- // Sample asset URL; You'll find URLs like these in asset and rich text elements
253
- const assetUrl = `https://assets-eu-01.kc-usercontent.com/ede994d8-bb05-01b5-9c33-8b65e7372306/4f45e0a8-4fc3-4143-a81f-55b7e4ce7daa/warrior.jpg`;
254
-
255
- const transformedUrl = transformImageUrl(assetUrl)
256
- .withDpr(2)
257
- .withCompression('lossless')
258
- .withQuality(4)
259
- .withHeight(200)
260
- .withWidth(100)
261
- .getUrl();
262
- ```
263
-
264
- ### Paging
265
-
266
- All listing queries support automatic paging. To use automatic paging, use `toAllPromise` extension method:
267
-
268
- ```typescript
269
- // this executed multiple HTTP requests until it gets all items
270
- const response = await deliveryClient.items().limitParameter(5).toAllPromise();
271
-
272
- // only gets 3 pages at maximum
273
- const response = await deliveryClient.items().limitParameter(5).toAllPromise({
274
- pages: 3
275
- });
276
- ```
277
-
278
- ### Resolving rich text elements
279
-
280
- [Rich text elements](https://kontent.ai/learn/reference/delivery-api#section/Rich-text-element) in Kontent.ai may
281
- contain linked items and components. For example, if you write a blog post, you might want to insert a video or
282
- testimonial to a specific place in your article.
283
-
284
- To learn how to work with Rich text element have a look at
285
- [@kontent-ai/rich-text-resolver](https://www.npmjs.com/package/@kontent-ai/rich-text-resolver) library.
286
-
287
- ## Get content types
288
-
289
- ```typescript
290
- deliveryClient.type('movie').toPromise();
291
- deliveryClient.types().toPromise();
292
- deliveryClient.types().toAllPromise();
293
- ```
294
-
295
- ## Get taxonomies
296
-
297
- ```typescript
298
- deliveryClient.taxonomy('taxonomyGroupName').toPromise();
299
- deliveryClient.taxonomies().toPromise();
300
- deliveryClient.taxonomies().toAllPromise();
301
- ```
302
-
303
- ## Proxy configuration
304
-
305
- If you want to use a proxy server, you need to use a different domain or otherwise transform the URL. By using `proxy`
306
- configuration option you can define your own base domains as well as URL format. This is useful if you need to for
307
- example hide the `environmentId` from the URL.
308
-
309
- `IDeliveryClientProxyConfig` offers 3 ways of configuring proxy URL:
310
-
311
- 1. `baseUrl` - Base URL used for all requests. Defaults to 'deliver.kontent.ai'
312
- 2. `basePreviewUrl` - Base url used for preview requests. Defaults to 'preview-deliver.kontent.ai'
313
- 3. `advancedProxyUrlResolver` - Resolver function where you get `IProxyUrlData` context data (includes domain, action,
314
- query parameters..) and can fully customize the final URL.
315
-
316
- Examples:
317
-
318
- ```typescript
319
- const client = createDeliveryClient({
320
- environmentId: '<YOUR_ENVIRONMENT_ID>',
321
- // Will be used instead of 'https://deliver.kontent.ai' for all requests.
322
- // Parameters, filters, project Id and other parts of the URL will use default values.
323
- proxy: {
324
- baseUrl: 'http://my-proxy.io'
325
- }
326
- });
327
- ```
328
-
329
- ```typescript
330
- const client = createDeliveryClient({
331
- environmentId: '<YOUR_ENVIRONMENT_ID>',
332
- proxy: {
333
- advancedProxyUrlResolver: (data) => {
334
- const action = data.action; // /items
335
- const domain = data.domain; // https://deliver.kontent.ai
336
- const environmentId = data.environmentId; // xxx
337
- const queryString = data.queryString; // e.g. ?depth=1&elements=xElement
338
- const queryParameters = data.queryParameters; // array with query parameters parameters
339
- const queryConfig = data.queryConfig; // query configuration
340
- return `http://my-proxy.io${action}${queryString}`; // proxy URL with omitted project Id
341
- }
342
- }
343
- });
344
- ```
345
-
346
- ## Error handling
347
-
348
- If the error originates in Kontent.ai (see
349
- [error responses](https://kontent.ai/learn/reference/delivery-api#section/SDKs)), you will get a `DeliveryError` object
350
- instance with more specific information. Otherwise, you will get the original error.
351
-
352
- ```typescript
353
- import { DeliveryError } from '@kontent-ai/delivery-sdk';
354
-
355
- try {
356
- await deliveryClient.item('invalid_codename').toPromise();
357
- } catch (error) {
358
- if (error instanceof DeliveryError) {
359
- // delivery specific error (e.g. item with codename not found...)
360
- console.log(err.message, err.errorCode);
361
- } else {
362
- // some other error
363
- console.log(error);
364
- }
365
- }
366
- ```
367
-
368
- ### Remapping json responses
369
-
370
- In some scenarios, you might want to store `json` response for later use and use SDK to map the response for you. There
371
- are 2 ways you can map previously stored `json`:
372
-
373
- ```typescript
374
- const result = await deliveryClient.item<Movie>('codename').toPromise();
375
- const json = result.response.data;
376
-
377
- // approach #1
378
- const remappedData = deliveryClient.mappingService.viewContentItemResponse<Movie>(json);
379
-
380
- // approach #2
381
- const remappedData = deliveryClient.item<Movie>(movieCodename).map(json);
382
- ```
383
-
384
- ### Handling circular references
385
-
386
- By default, the SDK automatically maps content items present in `linked items` & `rich text` elements. Linked items can
387
- reference other linked items in their tree (e.g. child item referencing parent) which may cause infinite nesting
388
- (circular reference). This behavior is not an issue for most scenarios, in fact it is beneficial as you can easily
389
- access all linked items. However, you cannot easily serialize such model. Using e.g. `JSON.stringify` would fail if
390
- there are circular references.
391
-
392
- For this reason, you may disable mapping of linked items with `linkedItemsReferenceHandler` configuration option.
393
-
394
- ```typescript
395
- const client = getTestDeliveryClient({
396
- environmentId: '<YOUR_ENVIRONMENT_ID>',
397
- linkedItemsReferenceHandler: 'ignore' // or 'map'
398
- });
399
- ```
400
-
401
- ### Using custom HTTP service
402
-
403
- The SDK allows you to inject your own instance of a class implementing the `IHttpService` interface. This way you can
404
- easily mock responses, implement your own http service, or modify the requests in some other way.
405
-
406
- Sample of a test `HttpService` implementation can be found at https://github.com/kontent-ai/core-sdk-js
407
-
408
- Once you have your `HttpService`, use it in delivery client initialization:
409
-
410
- ```typescript
411
- const deliveryClient = createDeliveryClient({
412
- environmentId: '<YOUR_ENVIRONMENT_ID>',
413
- httpService: YourHttpServiceImplementation
414
- });
415
- ```
416
-
417
- ### Use custom models for Custom elements
418
-
419
- You can register an `ElementResolver` to map custom elements into dedicated element models and work with data more
420
- effectively.
421
-
422
- For example, if you have a custom `color` element in your Kontent.ai project with json data like:
423
-
424
- ```json
425
- "color": {
426
- "type": "custom",
427
- "name": "Color",
428
- "value": "{\"red\":167,\"green\":96,\"blue\":197}"
429
- }
430
- ```
431
-
432
- You can create a `ColorElement` type with strongly typed properties for `red`, `green` & `blue` values that you will
433
- parse from the json.
434
-
435
- ```typescript
436
- import { ElementModels, Elements, createDeliveryClient } from '@kontent-ai/delivery-sdk';
437
-
438
- type ColorElement = Elements.CustomElement<{
439
- red: number;
440
- green: number;
441
- blue: number;
442
- }>;
443
- ```
444
-
445
- To resolve your custom element into `ColorElement`, use the `ElementResolver` in your delivery client config:
446
-
447
- ```typescript
448
- const client = createDeliveryClient({
449
- environmentId: '<YOUR_ENVIRONMENT_ID>',
450
- elementResolver: (elementWrapper) => {
451
- if (elementWrapper.rawElement.type === 'color') {
452
- const parsed = JSON.parse(elementWrapper.rawElement.value);
453
-
454
- return {
455
- red: parsed.red,
456
- green: parsed.green,
457
- blue: parsed.blue
458
- };
459
- }
460
-
461
- return undefined;
462
- }
463
- });
464
- ```
465
-
466
- You can then use this custom element type in your models:
467
-
468
- ```typescript
469
- type Movie = IContentItem<{
470
- color: ColorElement;
471
- title: Elements.TextElement;
472
- }>;
473
- ```
474
-
475
- ## UMD bundles
476
-
477
- When using UMD bundle and including this library in `script` tag on your `html` page, you can find it under the
478
- `kontentDelivery` global variable.
479
-
480
- Bundles are distributed in `dist/bundles` folder:
481
-
482
- - `dist/bundles/kontent-delivery.umd.js`
483
- - `dist/bundles/kontent-delivery.umd.min.js`
484
-
485
- ## Debugging
486
-
487
- ### Accessing request data
488
-
489
- Every response from this SDK contains additional debug data you can use to inspect when something is not right or if you
490
- need to access response headers or other network related properties.
491
-
492
- ```typescript
493
- const deliveryResponse = await createDeliveryClient({ environmentId: 'environmentId' })
494
- .item('itemCodename')
495
- .toPromise();
496
- const rawResponseData = deliveryResponse.response; // contains raw response data, headers, status etc..
497
- const responseHeaders = deliveryResponse.response.headers;
498
- ```
499
-
500
- ### Getting URL of a query
501
-
502
- In case you need to get the raw URL of a request before calling it, use the `getUrl()` method on any query.
503
-
504
- ```typescript
505
- const queryText = deliveryClient
506
- .items()
507
- .type('movie')
508
- .limitParameter(10)
509
- .orderParameter('system.codename', 'desc')
510
- .getUrl();
511
-
512
- console.log(queryText);
513
- // outputs:
514
- // https://deliver.kontent.ai/b52fa0db-84ec-4310-8f7c-3b94ed06644d/items?limit=10&order=system.codename[desc]&system.type=movie
515
- ```
516
-
517
- ## Testing
518
-
519
- Note: You need to have `Chrome` installed in order to run tests via Karma.
520
-
521
- - `npm run test:browser` Runs tests in Chrome
522
- - `npm run test:node` Runs tests in node.js
523
- - `npm run test:all` Runs all test
524
-
525
- > If you want to mock http responses, it is possible to use
526
- > [custom Http Service](https://github.com/kontent-ai/core-sdk-js#testing) as a part of the
527
- > [delivery client configuration](#client-configuration).
528
-
529
- ## Feedback & Contribution
530
-
531
- Feedback & Contributions are welcomed. Feel free to take/start an issue & submit PR.
1
+ [![npm version](https://badge.fury.io/js/%40kontent-ai%2Fdelivery-sdk.svg)](https://badge.fury.io/js/%40kontent-ai%2Fdelivery-sdk)
2
+ [![Build](https://github.com/kontent-ai/delivery-sdk-js/actions/workflows/test.yml/badge.svg)](https://github.com/kontent-ai/delivery-sdk-js/actions/workflows/test.yml)
3
+ [![npm](https://img.shields.io/npm/dt/@kontent-ai/delivery-sdk.svg)](https://www.npmjs.com/package/@kontent-ai/delivery-sdk)
4
+ [![Known Vulnerabilities](https://snyk.io/test/github/kontent-ai/delivery-sdk-js/badge.svg)](https://snyk.io/test/github/kontent-ai/delivery-sdk-js)
5
+ [![GitHub license](https://img.shields.io/github/license/kontent-ai/delivery-sdk-js.svg)](https://github.com/kontent-ai/delivery-sdk-js)
6
+ ![Gzip browser bundle](https://img.badgesize.io/https:/cdn.jsdelivr.net/npm/@kontent-ai/delivery-sdk/dist/bundles/kontent-delivery.umd.min.js?compression=gzip)
7
+ [![Discord](https://img.shields.io/discord/821885171984891914?label=Discord&logo=Discord&logoColor=white)](https://discord.gg/SKCxwPtevJ)
8
+
9
+ # JavaScript Delivery SDK Documentation
10
+
11
+ This library is build for fetching [Kontent.ai](https://kontent.ai/) data with `Delivery API`. Works in browser & node.
12
+
13
+ > [!TIP]
14
+ > It's **highly recommended** to use this library in combination with
15
+ > [Model Generator](https://www.npmjs.com/package/@kontent-ai/model-generator). Generating models will greatly increase
16
+ > type safety of your code and offer you an advanced intellisense.
17
+
18
+ # Kontent.ai Delivery SDK
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ npm i @kontent-ai/delivery-sdk --save
24
+ ```
25
+
26
+ ## Getting started
27
+
28
+ ```typescript
29
+ import { type IContentItem, type Elements, createDeliveryClient } from '@kontent-ai/delivery-sdk';
30
+
31
+ /**
32
+ * Generate models with @kontent-ai/model-generator
33
+ */
34
+ export type Movie = IContentItem<{
35
+ readonly title: Elements.TextElement;
36
+ readonly plot: Elements.RichTextElement;
37
+ readonly released: Elements.DateTimeElement;
38
+ readonly length: Elements.NumberElement;
39
+ readonly poster: Elements.AssetsElement;
40
+ readonly category: Elements.MultipleChoiceElement;
41
+ readonly stars: Elements.LinkedItemsElement<Actor>;
42
+ readonly seoname: Elements.UrlSlugElement;
43
+ readonly releasecategory: Elements.TaxonomyElement;
44
+ }>;
45
+
46
+ // Both `CoreDeliveryClient` and `CoreClientTypes` are types generated by @kontent-ai/model-generator
47
+ // By using the generated types you will get access to advanced intellisense & type safety
48
+ const deliveryClient: CoreDeliveryClient = createDeliveryClient<CoreClientTypes>({
49
+ environmentId: '<YOUR_ENVIRONMENT_ID>'
50
+ });
51
+
52
+ // fetch items
53
+ const response = await deliveryClient.items<Movie>().type('<CONTENT_TYPE_CODENAME>').toPromise();
54
+
55
+ // read data of first item
56
+ const movieText = response.data.items[0].elements.title.value;
57
+ ```
58
+
59
+ ## Configuration
60
+
61
+ | Property | type | description |
62
+ | ---------------------------- | :--------------------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
63
+ | environmentId | string | environmentId of your Kontent.ai project |
64
+ | elementResolver? | ElementResolver | Element resolver used to map custom elements |
65
+ | previewApiKey? | string | Preview API key used to get unpublished content items |
66
+ | defaultLanguage? | string | Sets default language that will be used for all queries unless overridden with query parameters |
67
+ | proxy? | IDeliveryClientProxyConfig | Can be used to configure custom URLs. Useful when you use reverse proxy or have a need to transform URL - e.g. to remove 'environmentId' |
68
+ | secureApiKey? | string | Secured API key: Use secured API only when running on Node.JS server, otherwise you can expose your key |
69
+ | defaultQueryConfig? | IQueryConfig | Default configuration for all queries. Can be overridden by individual queries |
70
+ | httpService ? | IHttpService | Can be used to inject custom http service for performing requests |
71
+ | globalHeaders? | (queryConfig: IQueryConfig) => IHeader[] | Adds ability to add extra headers to each http request |
72
+ | retryStrategy? | IRetryStrategyOptions | Retry strategy configuration |
73
+ | linkedItemsReferenceHandler? | LinkedItemsReferenceHandler | Indicates if content items are automatically mapped. Available values: 'map' or 'ignore' |
74
+ | assetsDomain? | string | Custom domain for assets. Changes url of assets in both asset & rich text elements |
75
+ | defaultRenditionPreset? | string | Codename of rendition preset to be applied by default to the base asset URL path when present. When set, the SDK will provide the URL of customized images by default. Right now the only supported preset codename is `default`. |
76
+ | excludeArchivedItems? | boolean | Can be used to exclude archived items from all queries by default. Only applicable when preview API is used. |
77
+
78
+ ### Querying
79
+
80
+ The SDK supports the following query parameters: `depthParameter`, `elementsParameter`, `excludeElementsParameter`,
81
+ `limitParameter`, `orderParameter`, `skipParameter` and `languageParameter`. For more information about the parameters,
82
+ see the [SDK query methods](#filter-content) below. You can also head over to
83
+ [Delivery API reference](https://kontent.ai/learn/docs/apis/openapi/delivery-api/#tag/Filtering-parameters).
84
+
85
+ ```typescript
86
+ // Gets 5 items based on the Movie type
87
+ deliveryClient.items<Movie>().type('movie').limitParameter(5).skipParameter(2).toPromise();
88
+ ```
89
+
90
+ | Filter |
91
+ | -------------------------- |
92
+ | `depthParameter` |
93
+ | `elementsParameter` |
94
+ | `excludeElementsParameter` |
95
+ | `limitParameter` |
96
+ | `orderParameter` |
97
+ | `skipParameter` |
98
+ | `languageParameter` |
99
+
100
+ #### Filtering
101
+
102
+ Filters are also considered query parameters and can be combined. See
103
+ [Content filtering in API reference](https://kontent.ai/learn/docs/apis/openapi/delivery-api/#tag/Filtering-parameters)
104
+ for more examples.
105
+
106
+ ```typescript
107
+ // Gets items based on the Movie type with 'Warrior' in their 'Title' element
108
+ deliveryClient.items<Movie>().type('movie').equalsFilter('elements.title', 'Warrior').toPromise();
109
+ ```
110
+
111
+ | Filter |
112
+ | -------------------------- |
113
+ | `type` |
114
+ | `types` |
115
+ | `allFilter` |
116
+ | `anyFilter` |
117
+ | `containsFilter` |
118
+ | `equalsFilter` |
119
+ | `greaterThanFilter` |
120
+ | `greaterThanOrEqualFilter` |
121
+ | `inFilter` |
122
+ | `lessThanFilter` |
123
+ | `lessThanOrEqualFilter` |
124
+ | `rangeFilter` |
125
+ | `emptyFilter` |
126
+ | `NotEmptyFilter` |
127
+ | `notEqualsFilter` |
128
+ | `notInFilter` |
129
+
130
+ #### Soring
131
+
132
+ You can sort data by using any of the following methods:
133
+
134
+ ```typescript
135
+ deliveryClient.items<Movie>().type('movie').orderByDescending('elements.title').toPromise();
136
+ deliveryClient.items<Movie>().type('movie').orderByAscending('elements.title').toPromise();
137
+ deliveryClient.items<Movie>().type('movie').orderParameter('elements.title', 'desc').toPromise();
138
+ ```
139
+
140
+ ### Execute queries with a custom URL
141
+
142
+ When you have an URL (i.e. for `next page` in paging, for testing purposes or just if you prefer to build it on your
143
+ own) and still want to leverage SDK functionality such as type mapping, property resolving etc., use `withUrl` parameter
144
+ on any query such as:
145
+
146
+ ```typescript
147
+ deliveryClient
148
+ .items<Movie>()
149
+ .withUrl('https://deliver.kontent.ai/da5abe9f-fdad-4168-97cd-b3464be2ccb9/items?system.type=movie')
150
+ .toPromise();
151
+ ```
152
+
153
+ ### Custom parameters
154
+
155
+ In case you need to use custom parameters to build up an URL, use `withParameter` method:
156
+
157
+ ```typescript
158
+ deliveryClient.items<Movie>().withParameter('name', 'value').toPromise();
159
+ ```
160
+
161
+ ### Get localized items
162
+
163
+ You can specify [language of items](https://kontent.ai/learn/tutorials/manage-kontent/projects/set-up-languages) with
164
+ `languageParameter` of a particular query. You can also define default language that will be used if `languageParameter`
165
+ is not used during the initialization of delivery client.
166
+
167
+ ```typescript
168
+ import { createDeliveryClient } from '@kontent-ai/delivery-sdk';
169
+
170
+ var deliveryClient = new createDeliveryClient({
171
+ environmentId: '<YOUR_ENVIRONMENT_ID>',
172
+ defaultLanguage: 'es'
173
+ });
174
+
175
+ // Gets items in 'es' language because it is marked as default
176
+ deliveryClient.item('warrior').toPromise();
177
+
178
+ // Gets items in 'en' language because language parameter has priority over the default one
179
+ deliveryClient.item('warrior').languageParameter(`en`).toPromise();
180
+ ```
181
+
182
+ ### Preview mode
183
+
184
+ You can enable the preview mode either globally (when [initializing the DeliveryClient](#how-to-use-deliveryclient)) or
185
+ per query. In each case, you need to set `previewApiKey` in the delivery client global configuration.
186
+
187
+ #### Enable preview mode globally
188
+
189
+ ```typescript
190
+ import { createDeliveryClient } from '@kontent-ai/delivery-sdk';
191
+
192
+ const deliveryClient = createDeliveryClient({
193
+ environmentId: '<YOUR_ENVIRONMENT_ID>';
194
+ previewApiKey: '<YOUR_PREVIEW_API_KEY>',
195
+ defaultQueryConfig: {
196
+ usePreviewMode: true
197
+ }
198
+ });
199
+ ```
200
+
201
+ #### Enable preview mode per query
202
+
203
+ ```typescript
204
+ deliveryClient
205
+ .items()
206
+ .queryConfig({
207
+ usePreviewMode: true
208
+ })
209
+ .toPromise();
210
+ ```
211
+
212
+ ### Secure Delivery API
213
+
214
+ Using the Delivery API with
215
+ [secure access](https://kontent.ai/learn/tutorials/develop-apps/build-strong-foundation/restrict-public-access) enabled
216
+ is recommend only when the request is not being executed on the client (browser) because otherwise you will expose the
217
+ API key publicly.
218
+
219
+ ```typescript
220
+ import { createDeliveryClient } from '@kontent-ai/delivery-sdk';
221
+
222
+ const deliveryClient = createDeliveryClient({
223
+ environmentId: '<YOUR_ENVIRONMENT_ID>';
224
+ secureApiKey: '<YOUR_SECURE_ACCESS_KEY>',
225
+ defaultQueryConfig: {
226
+ // Enabled secure access for all queries
227
+ useSecuredMode: true
228
+ }
229
+ });
230
+ ```
231
+
232
+ As with [preview mode](#preview-mode), you can also override global settings on query level.
233
+
234
+ ```typescript
235
+ deliveryClient
236
+ .items()
237
+ .queryConfig({
238
+ // Enables secure access only for this query
239
+ useSecuredMode: true
240
+ })
241
+ .toPromise();
242
+ ```
243
+
244
+ ### Image transformation
245
+
246
+ Use `ImageUrlBuilder` for your [image transformations](https://kontent.ai/learn/reference/image-transformation) on asset
247
+ URLs.
248
+
249
+ ```typescript
250
+ import { transformImageUrl } from '@kontent-ai/delivery-sdk';
251
+
252
+ // Sample asset URL; You'll find URLs like these in asset and rich text elements
253
+ const assetUrl = `https://assets-eu-01.kc-usercontent.com/ede994d8-bb05-01b5-9c33-8b65e7372306/4f45e0a8-4fc3-4143-a81f-55b7e4ce7daa/warrior.jpg`;
254
+
255
+ const transformedUrl = transformImageUrl(assetUrl)
256
+ .withDpr(2)
257
+ .withCompression('lossless')
258
+ .withQuality(4)
259
+ .withHeight(200)
260
+ .withWidth(100)
261
+ .getUrl();
262
+ ```
263
+
264
+ ### Paging
265
+
266
+ All listing queries support automatic paging. To use automatic paging, use `toAllPromise` extension method:
267
+
268
+ ```typescript
269
+ // this executed multiple HTTP requests until it gets all items
270
+ const response = await deliveryClient.items().limitParameter(5).toAllPromise();
271
+
272
+ // only gets 3 pages at maximum
273
+ const response = await deliveryClient.items().limitParameter(5).toAllPromise({
274
+ pages: 3
275
+ });
276
+ ```
277
+
278
+ ### Resolving rich text elements
279
+
280
+ [Rich text elements](https://kontent.ai/learn/reference/delivery-api#section/Rich-text-element) in Kontent.ai may
281
+ contain linked items and components. For example, if you write a blog post, you might want to insert a video or
282
+ testimonial to a specific place in your article.
283
+
284
+ To learn how to work with Rich text element have a look at
285
+ [@kontent-ai/rich-text-resolver](https://www.npmjs.com/package/@kontent-ai/rich-text-resolver) library.
286
+
287
+ ## Get content types
288
+
289
+ ```typescript
290
+ deliveryClient.type('movie').toPromise();
291
+ deliveryClient.types().toPromise();
292
+ deliveryClient.types().toAllPromise();
293
+ ```
294
+
295
+ ## Get taxonomies
296
+
297
+ ```typescript
298
+ deliveryClient.taxonomy('taxonomyGroupName').toPromise();
299
+ deliveryClient.taxonomies().toPromise();
300
+ deliveryClient.taxonomies().toAllPromise();
301
+ ```
302
+
303
+ ## Proxy configuration
304
+
305
+ If you want to use a proxy server, you need to use a different domain or otherwise transform the URL. By using `proxy`
306
+ configuration option you can define your own base domains as well as URL format. This is useful if you need to for
307
+ example hide the `environmentId` from the URL.
308
+
309
+ `IDeliveryClientProxyConfig` offers 3 ways of configuring proxy URL:
310
+
311
+ 1. `baseUrl` - Base URL used for all requests. Defaults to 'deliver.kontent.ai'
312
+ 2. `basePreviewUrl` - Base url used for preview requests. Defaults to 'preview-deliver.kontent.ai'
313
+ 3. `advancedProxyUrlResolver` - Resolver function where you get `IProxyUrlData` context data (includes domain, action,
314
+ query parameters..) and can fully customize the final URL.
315
+
316
+ Examples:
317
+
318
+ ```typescript
319
+ const client = createDeliveryClient({
320
+ environmentId: '<YOUR_ENVIRONMENT_ID>',
321
+ // Will be used instead of 'https://deliver.kontent.ai' for all requests.
322
+ // Parameters, filters, project Id and other parts of the URL will use default values.
323
+ proxy: {
324
+ baseUrl: 'http://my-proxy.io'
325
+ }
326
+ });
327
+ ```
328
+
329
+ ```typescript
330
+ const client = createDeliveryClient({
331
+ environmentId: '<YOUR_ENVIRONMENT_ID>',
332
+ proxy: {
333
+ advancedProxyUrlResolver: (data) => {
334
+ const action = data.action; // /items
335
+ const domain = data.domain; // https://deliver.kontent.ai
336
+ const environmentId = data.environmentId; // xxx
337
+ const queryString = data.queryString; // e.g. ?depth=1&elements=xElement
338
+ const queryParameters = data.queryParameters; // array with query parameters parameters
339
+ const queryConfig = data.queryConfig; // query configuration
340
+ return `http://my-proxy.io${action}${queryString}`; // proxy URL with omitted project Id
341
+ }
342
+ }
343
+ });
344
+ ```
345
+
346
+ ## Error handling
347
+
348
+ If the error originates in Kontent.ai (see
349
+ [error responses](https://kontent.ai/learn/reference/delivery-api#section/SDKs)), you will get a `DeliveryError` object
350
+ instance with more specific information. Otherwise, you will get the original error.
351
+
352
+ ```typescript
353
+ import { DeliveryError } from '@kontent-ai/delivery-sdk';
354
+
355
+ try {
356
+ await deliveryClient.item('invalid_codename').toPromise();
357
+ } catch (error) {
358
+ if (error instanceof DeliveryError) {
359
+ // delivery specific error (e.g. item with codename not found...)
360
+ console.log(err.message, err.errorCode);
361
+ } else {
362
+ // some other error
363
+ console.log(error);
364
+ }
365
+ }
366
+ ```
367
+
368
+ ### Remapping json responses
369
+
370
+ In some scenarios, you might want to store `json` response for later use and use SDK to map the response for you. There
371
+ are 2 ways you can map previously stored `json`:
372
+
373
+ ```typescript
374
+ const result = await deliveryClient.item<Movie>('codename').toPromise();
375
+ const json = result.response.data;
376
+
377
+ // approach #1
378
+ const remappedData = deliveryClient.mappingService.viewContentItemResponse<Movie>(json);
379
+
380
+ // approach #2
381
+ const remappedData = deliveryClient.item<Movie>(movieCodename).map(json);
382
+ ```
383
+
384
+ ### Handling circular references
385
+
386
+ By default, the SDK automatically maps content items present in `linked items` & `rich text` elements. Linked items can
387
+ reference other linked items in their tree (e.g. child item referencing parent) which may cause infinite nesting
388
+ (circular reference). This behavior is not an issue for most scenarios, in fact it is beneficial as you can easily
389
+ access all linked items. However, you cannot easily serialize such model. Using e.g. `JSON.stringify` would fail if
390
+ there are circular references.
391
+
392
+ For this reason, you may disable mapping of linked items with `linkedItemsReferenceHandler` configuration option.
393
+
394
+ ```typescript
395
+ const client = getTestDeliveryClient({
396
+ environmentId: '<YOUR_ENVIRONMENT_ID>',
397
+ linkedItemsReferenceHandler: 'ignore' // or 'map'
398
+ });
399
+ ```
400
+
401
+ ### Using custom HTTP service
402
+
403
+ The SDK allows you to inject your own instance of a class implementing the `IHttpService` interface. This way you can
404
+ easily mock responses, implement your own http service, or modify the requests in some other way.
405
+
406
+ Sample of a test `HttpService` implementation can be found at https://github.com/kontent-ai/core-sdk-js
407
+
408
+ Once you have your `HttpService`, use it in delivery client initialization:
409
+
410
+ ```typescript
411
+ const deliveryClient = createDeliveryClient({
412
+ environmentId: '<YOUR_ENVIRONMENT_ID>',
413
+ httpService: YourHttpServiceImplementation
414
+ });
415
+ ```
416
+
417
+ ### Use custom models for Custom elements
418
+
419
+ You can register an `ElementResolver` to map custom elements into dedicated element models and work with data more
420
+ effectively.
421
+
422
+ For example, if you have a custom `color` element in your Kontent.ai project with json data like:
423
+
424
+ ```json
425
+ "color": {
426
+ "type": "custom",
427
+ "name": "Color",
428
+ "value": "{\"red\":167,\"green\":96,\"blue\":197}"
429
+ }
430
+ ```
431
+
432
+ You can create a `ColorElement` type with strongly typed properties for `red`, `green` & `blue` values that you will
433
+ parse from the json.
434
+
435
+ ```typescript
436
+ import { ElementModels, Elements, createDeliveryClient } from '@kontent-ai/delivery-sdk';
437
+
438
+ type ColorElement = Elements.CustomElement<{
439
+ red: number;
440
+ green: number;
441
+ blue: number;
442
+ }>;
443
+ ```
444
+
445
+ To resolve your custom element into `ColorElement`, use the `ElementResolver` in your delivery client config:
446
+
447
+ ```typescript
448
+ const client = createDeliveryClient({
449
+ environmentId: '<YOUR_ENVIRONMENT_ID>',
450
+ elementResolver: (elementWrapper) => {
451
+ if (elementWrapper.rawElement.type === 'color') {
452
+ const parsed = JSON.parse(elementWrapper.rawElement.value);
453
+
454
+ return {
455
+ red: parsed.red,
456
+ green: parsed.green,
457
+ blue: parsed.blue
458
+ };
459
+ }
460
+
461
+ return undefined;
462
+ }
463
+ });
464
+ ```
465
+
466
+ You can then use this custom element type in your models:
467
+
468
+ ```typescript
469
+ type Movie = IContentItem<{
470
+ color: ColorElement;
471
+ title: Elements.TextElement;
472
+ }>;
473
+ ```
474
+
475
+ ## UMD bundles
476
+
477
+ When using UMD bundle and including this library in `script` tag on your `html` page, you can find it under the
478
+ `kontentDelivery` global variable.
479
+
480
+ Bundles are distributed in `dist/bundles` folder:
481
+
482
+ - `dist/bundles/kontent-delivery.umd.js`
483
+ - `dist/bundles/kontent-delivery.umd.min.js`
484
+
485
+ ## Debugging
486
+
487
+ ### Accessing request data
488
+
489
+ Every response from this SDK contains additional debug data you can use to inspect when something is not right or if you
490
+ need to access response headers or other network related properties.
491
+
492
+ ```typescript
493
+ const deliveryResponse = await createDeliveryClient({ environmentId: 'environmentId' })
494
+ .item('itemCodename')
495
+ .toPromise();
496
+ const rawResponseData = deliveryResponse.response; // contains raw response data, headers, status etc..
497
+ const responseHeaders = deliveryResponse.response.headers;
498
+ ```
499
+
500
+ ### Getting URL of a query
501
+
502
+ In case you need to get the raw URL of a request before calling it, use the `getUrl()` method on any query.
503
+
504
+ ```typescript
505
+ const queryText = deliveryClient
506
+ .items()
507
+ .type('movie')
508
+ .limitParameter(10)
509
+ .orderParameter('system.codename', 'desc')
510
+ .getUrl();
511
+
512
+ console.log(queryText);
513
+ // outputs:
514
+ // https://deliver.kontent.ai/b52fa0db-84ec-4310-8f7c-3b94ed06644d/items?limit=10&order=system.codename[desc]&system.type=movie
515
+ ```
516
+
517
+ ## Testing
518
+
519
+ Note: You need to have `Chrome` installed in order to run tests via Karma.
520
+
521
+ - `npm run test:browser` Runs tests in Chrome
522
+ - `npm run test:node` Runs tests in node.js
523
+ - `npm run test:all` Runs all test
524
+
525
+ > If you want to mock http responses, it is possible to use
526
+ > [custom Http Service](https://github.com/kontent-ai/core-sdk-js#testing) as a part of the
527
+ > [delivery client configuration](#client-configuration).
528
+
529
+ ## Feedback & Contribution
530
+
531
+ Feedback & Contributions are welcomed. Feel free to take/start an issue & submit PR.