@contentful/optimization-api-client 0.1.0-alpha8 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -218
- package/THIRD_PARTY_NOTICES.txt +2038 -0
- package/dist/199.mjs +2 -0
- package/dist/649.mjs +131 -0
- package/dist/649.mjs.map +1 -0
- package/dist/api-schemas.cjs +60 -0
- package/dist/api-schemas.cjs.map +1 -0
- package/dist/api-schemas.d.cts +4 -0
- package/dist/api-schemas.d.mts +4 -0
- package/dist/api-schemas.d.ts +4 -0
- package/dist/api-schemas.mjs +2 -0
- package/dist/index.cjs +452 -580
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +520 -1042
- package/dist/index.d.mts +520 -1042
- package/dist/index.d.ts +868 -8
- package/dist/index.mjs +115 -298
- package/dist/index.mjs.map +1 -1
- package/dist/logger.cjs +207 -0
- package/dist/logger.cjs.map +1 -0
- package/dist/logger.d.cts +287 -0
- package/dist/logger.d.mts +287 -0
- package/dist/logger.d.ts +287 -0
- package/dist/logger.mjs +1 -0
- package/package.json +37 -7
- package/dist/ApiClient.d.ts +0 -74
- package/dist/ApiClient.d.ts.map +0 -1
- package/dist/ApiClient.js +0 -61
- package/dist/ApiClient.js.map +0 -1
- package/dist/ApiClientBase.d.ts +0 -113
- package/dist/ApiClientBase.d.ts.map +0 -1
- package/dist/ApiClientBase.js +0 -94
- package/dist/ApiClientBase.js.map +0 -1
- package/dist/builders/EventBuilder.d.ts +0 -589
- package/dist/builders/EventBuilder.d.ts.map +0 -1
- package/dist/builders/EventBuilder.js +0 -349
- package/dist/builders/EventBuilder.js.map +0 -1
- package/dist/builders/index.d.ts +0 -3
- package/dist/builders/index.d.ts.map +0 -1
- package/dist/builders/index.js +0 -3
- package/dist/builders/index.js.map +0 -1
- package/dist/experience/ExperienceApiClient.d.ts +0 -267
- package/dist/experience/ExperienceApiClient.d.ts.map +0 -1
- package/dist/experience/ExperienceApiClient.js +0 -324
- package/dist/experience/ExperienceApiClient.js.map +0 -1
- package/dist/experience/index.d.ts +0 -4
- package/dist/experience/index.d.ts.map +0 -1
- package/dist/experience/index.js +0 -4
- package/dist/experience/index.js.map +0 -1
- package/dist/fetch/Fetch.d.ts +0 -96
- package/dist/fetch/Fetch.d.ts.map +0 -1
- package/dist/fetch/Fetch.js +0 -27
- package/dist/fetch/Fetch.js.map +0 -1
- package/dist/fetch/createProtectedFetchMethod.d.ts +0 -40
- package/dist/fetch/createProtectedFetchMethod.d.ts.map +0 -1
- package/dist/fetch/createProtectedFetchMethod.js +0 -53
- package/dist/fetch/createProtectedFetchMethod.js.map +0 -1
- package/dist/fetch/createRetryFetchMethod.d.ts +0 -60
- package/dist/fetch/createRetryFetchMethod.d.ts.map +0 -1
- package/dist/fetch/createRetryFetchMethod.js +0 -138
- package/dist/fetch/createRetryFetchMethod.js.map +0 -1
- package/dist/fetch/createTimeoutFetchMethod.d.ts +0 -51
- package/dist/fetch/createTimeoutFetchMethod.d.ts.map +0 -1
- package/dist/fetch/createTimeoutFetchMethod.js +0 -51
- package/dist/fetch/createTimeoutFetchMethod.js.map +0 -1
- package/dist/fetch/index.d.ts +0 -7
- package/dist/fetch/index.d.ts.map +0 -1
- package/dist/fetch/index.js +0 -7
- package/dist/fetch/index.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -8
- package/dist/index.js.map +0 -1
- package/dist/insights/InsightsApiClient.d.ts +0 -130
- package/dist/insights/InsightsApiClient.d.ts.map +0 -1
- package/dist/insights/InsightsApiClient.js +0 -143
- package/dist/insights/InsightsApiClient.js.map +0 -1
- package/dist/insights/index.d.ts +0 -4
- package/dist/insights/index.d.ts.map +0 -1
- package/dist/insights/index.js +0 -4
- package/dist/insights/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<p align="center">
|
|
2
2
|
<a href="https://www.contentful.com/developers/docs/personalization/">
|
|
3
|
-
<img alt="Contentful Logo" title="Contentful" src="
|
|
3
|
+
<img alt="Contentful Logo" title="Contentful" src="https://raw.githubusercontent.com/contentful/optimization/optimization-api-client-v1.0.0/contentful-icon.png" width="150">
|
|
4
4
|
</a>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
@@ -10,45 +10,40 @@
|
|
|
10
10
|
|
|
11
11
|
<div align="center">
|
|
12
12
|
|
|
13
|
-
[
|
|
14
|
-
[Contributing](/CONTRIBUTING.md)
|
|
13
|
+
[Guides](https://contentful.github.io/optimization/documents/Documentation.Guides.html) ·
|
|
14
|
+
[Reference](https://contentful.github.io/optimization) · [Contributing](https://github.com/contentful/optimization/blob/optimization-api-client-v1.0.0/CONTRIBUTING.md)
|
|
15
15
|
|
|
16
16
|
</div>
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
Experience and Insights APIs, which serve its Personalization and Analytics products.
|
|
20
|
-
|
|
21
|
-
> [!NOTE]
|
|
18
|
+
> [!WARNING]
|
|
22
19
|
>
|
|
23
|
-
>
|
|
20
|
+
> The Optimization SDK Suite is pre-release (alpha). Breaking changes can be published at any time.
|
|
21
|
+
|
|
22
|
+
The Contentful Optimization API Client provides low-level transport for the Experience API and
|
|
23
|
+
Insights API. Application-facing SDKs compose this package with event builders, state management,
|
|
24
|
+
queueing, and runtime-specific defaults.
|
|
25
|
+
|
|
26
|
+
We recommend starting applications with Web, React Web, Node, or React Native SDKs. Use this package
|
|
27
|
+
directly when building or maintaining SDK layers, tests, tooling, or first-party integrations that
|
|
28
|
+
need raw API access.
|
|
24
29
|
|
|
25
30
|
<details>
|
|
26
31
|
<summary>Table of Contents</summary>
|
|
27
32
|
<!-- mtoc-start -->
|
|
28
33
|
|
|
29
|
-
- [Getting
|
|
30
|
-
- [
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- [Analytics Options](#analytics-options)
|
|
34
|
-
- [Personalization Options](#personalization-options)
|
|
35
|
-
- [Working With the APIs](#working-with-the-apis)
|
|
34
|
+
- [Getting started](#getting-started)
|
|
35
|
+
- [When to use this package](#when-to-use-this-package)
|
|
36
|
+
- [Common configuration](#common-configuration)
|
|
37
|
+
- [API surface](#api-surface)
|
|
36
38
|
- [Experience API](#experience-api)
|
|
37
|
-
- [Get Profile data](#get-profile-data)
|
|
38
|
-
- [Create a New Profile](#create-a-new-profile)
|
|
39
|
-
- [Update an Existing Profile](#update-an-existing-profile)
|
|
40
|
-
- [Upsert a Profile](#upsert-a-profile)
|
|
41
|
-
- [Upsert Many Profiles](#upsert-many-profiles)
|
|
42
39
|
- [Insights API](#insights-api)
|
|
43
|
-
|
|
44
|
-
- [
|
|
45
|
-
- [Event Builder Configuration](#event-builder-configuration)
|
|
46
|
-
- [Event Builder Configured Methods](#event-builder-configured-methods)
|
|
40
|
+
- [Fetch helpers](#fetch-helpers)
|
|
41
|
+
- [Related](#related)
|
|
47
42
|
|
|
48
43
|
<!-- mtoc-end -->
|
|
49
44
|
</details>
|
|
50
45
|
|
|
51
|
-
## Getting
|
|
46
|
+
## Getting started
|
|
52
47
|
|
|
53
48
|
Install using an NPM-compatible package manager, pnpm for example:
|
|
54
49
|
|
|
@@ -56,227 +51,124 @@ Install using an NPM-compatible package manager, pnpm for example:
|
|
|
56
51
|
pnpm install @contentful/optimization-api-client
|
|
57
52
|
```
|
|
58
53
|
|
|
59
|
-
Import the API client; both CJS and ESM module systems are supported, ESM
|
|
54
|
+
Import and initialize the unified API client; both CJS and ESM module systems are supported, ESM
|
|
55
|
+
preferred:
|
|
60
56
|
|
|
61
57
|
```ts
|
|
62
58
|
import { ApiClient } from '@contentful/optimization-api-client'
|
|
63
|
-
```
|
|
64
59
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
60
|
+
const client = new ApiClient({
|
|
61
|
+
clientId: 'your-client-id',
|
|
62
|
+
environment: 'main',
|
|
63
|
+
})
|
|
69
64
|
```
|
|
70
65
|
|
|
71
|
-
##
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
|
80
|
-
|
|
|
81
|
-
| `
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
|
91
|
-
|
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
96
|
-
| `
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
> [!NOTE]
|
|
127
|
-
>
|
|
128
|
-
> All options except `baseUrl` may also be provided on a per-request basis.
|
|
129
|
-
|
|
130
|
-
## Working With the APIs
|
|
66
|
+
## When to use this package
|
|
67
|
+
|
|
68
|
+
Use `@contentful/optimization-api-client` when you need direct low-level access to the Experience
|
|
69
|
+
API or Insights API transport surface. Use an application-facing SDK when you need optimization
|
|
70
|
+
state, consent handling, event builders, entry resolution, tracking, or platform defaults.
|
|
71
|
+
|
|
72
|
+
## Common configuration
|
|
73
|
+
|
|
74
|
+
| Option | Required? | Default | Description |
|
|
75
|
+
| -------------- | --------- | ---------------------------- | ----------------------------------------------------------- |
|
|
76
|
+
| `clientId` | Yes | N/A | Shared API key for Experience API and Insights API requests |
|
|
77
|
+
| `environment` | No | `'main'` | Contentful environment identifier |
|
|
78
|
+
| `experience` | No | See Experience options below | Experience API endpoint and default request options |
|
|
79
|
+
| `insights` | No | See Insights options below | Insights API endpoint options |
|
|
80
|
+
| `fetchOptions` | No | SDK defaults | Fetch timeout and retry behavior |
|
|
81
|
+
|
|
82
|
+
Common Experience API options:
|
|
83
|
+
|
|
84
|
+
| Option | Required? | Default | Description |
|
|
85
|
+
| ----------------- | --------- | ------------------------------------- | ----------------------------------------------- |
|
|
86
|
+
| `baseUrl` | No | `'https://experience.ninetailed.co/'` | Base URL for the Experience API |
|
|
87
|
+
| `enabledFeatures` | No | `['ip-enrichment', 'location']` | Experience API features for mutation requests |
|
|
88
|
+
| `ip` | No | `undefined` | IP address override for Experience API analysis |
|
|
89
|
+
| `locale` | No | API default | Locale query parameter for localized responses |
|
|
90
|
+
| `plainText` | No | Endpoint-specific | Sends single-profile mutation endpoints as text |
|
|
91
|
+
| `preflight` | No | `false` | Aggregates a profile state without storing it |
|
|
92
|
+
|
|
93
|
+
Experience mutation request options except `baseUrl` can also be provided per mutation request.
|
|
94
|
+
`getProfile` is a read request and only uses `locale` from per-call options; mutation-only options
|
|
95
|
+
such as `enabledFeatures`, `ip`, `plainText`, and `preflight` do not apply. Single-profile mutation
|
|
96
|
+
requests default to `plainText: true` and send `text/plain` unless overridden. Batch profile updates
|
|
97
|
+
with `upsertManyProfiles` are the JSON-default exception and use `plainText: false` by default.
|
|
98
|
+
`locale` is sent as the Experience API `locale` query parameter and can localize profile fields such
|
|
99
|
+
as `location.city` and `location.country`. Higher-level SDK merge-tag helpers resolve against the
|
|
100
|
+
profile values returned by the Experience API, so applications that render localized Contentful
|
|
101
|
+
entries commonly pass the same locale used for the CDA entry fetch. Pass a valid locale tag; invalid
|
|
102
|
+
locale syntax can fail Experience API request validation. See
|
|
103
|
+
[Locale handling in the Optimization SDK Suite](https://contentful.github.io/optimization/documents/Documentation.Concepts.Locale_handling_in_the_Optimization_SDK_Suite.html)
|
|
104
|
+
for how this request locale relates to Contentful and SDK-resolved locales.
|
|
105
|
+
|
|
106
|
+
Common Insights API options:
|
|
107
|
+
|
|
108
|
+
| Option | Required? | Default | Description |
|
|
109
|
+
| --------- | --------- | ------------------------------------------ | ----------------------------- |
|
|
110
|
+
| `baseUrl` | No | `'https://ingest.insights.ninetailed.co/'` | Base URL for the Insights API |
|
|
111
|
+
|
|
112
|
+
Common `fetchOptions` are `fetchMethod`, `requestTimeout`, `retries`, `intervalTimeout`,
|
|
113
|
+
`onFailedAttempt`, and `onRequestTimeout`. Default retries intentionally apply only to HTTP `503`
|
|
114
|
+
responses.
|
|
115
|
+
|
|
116
|
+
For every option, callback payload, request type, and response type, use the generated
|
|
117
|
+
[API Client reference](https://contentful.github.io/optimization/modules/_contentful_optimization-api-client.html).
|
|
118
|
+
|
|
119
|
+
## API surface
|
|
131
120
|
|
|
132
121
|
### Experience API
|
|
133
122
|
|
|
134
|
-
Experience API methods are scoped to
|
|
135
|
-
personalization methods return a `Promise` that resolves with the following data:
|
|
136
|
-
|
|
137
|
-
```json
|
|
138
|
-
{
|
|
139
|
-
"profile": {
|
|
140
|
-
/* User profile data */
|
|
141
|
-
},
|
|
142
|
-
"personalizations": [
|
|
143
|
-
{
|
|
144
|
-
/* Personalization/experience configuration for the associated profile */
|
|
145
|
-
}
|
|
146
|
-
],
|
|
147
|
-
"changes": [
|
|
148
|
-
{
|
|
149
|
-
/* Similar to `personalizations` but currently used for Custom Flags */
|
|
150
|
-
}
|
|
151
|
-
]
|
|
152
|
-
}
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
#### Get Profile data
|
|
156
|
-
|
|
157
|
-
```ts
|
|
158
|
-
const client = new ApiClient({ clientId: 'abc123' })
|
|
159
|
-
const { profile } = await client.personalization.getProfile('profile-123', { locale: 'de-DE' })
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
#### Create a New Profile
|
|
163
|
-
|
|
164
|
-
```ts
|
|
165
|
-
const client = new ApiClient({ clientId: 'abc123' })
|
|
166
|
-
const { profile } = await client.personalization.createProfile({ events: [...] }, { locale: 'de-DE' })
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
#### Update an Existing Profile
|
|
123
|
+
Experience API methods are scoped to `client.experience` and return profile and optimization data:
|
|
170
124
|
|
|
171
125
|
```ts
|
|
172
|
-
const
|
|
173
|
-
const { profile } = await client.personalization.updateProfile(
|
|
126
|
+
const { profile, selectedOptimizations, changes } = await client.experience.upsertProfile(
|
|
174
127
|
{
|
|
175
|
-
profileId: 'profile-
|
|
176
|
-
events: [
|
|
128
|
+
profileId: 'profile-id',
|
|
129
|
+
events: [pageEvent],
|
|
177
130
|
},
|
|
178
|
-
{ locale: 'de-DE' }
|
|
179
|
-
)
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
#### Upsert a Profile
|
|
183
|
-
|
|
184
|
-
```ts
|
|
185
|
-
const client = new ApiClient({ clientId: 'abc123' })
|
|
186
|
-
const { profile } = await client.personalization.upsertProfile(
|
|
187
|
-
{
|
|
188
|
-
profileId,
|
|
189
|
-
events: [...],
|
|
190
|
-
},
|
|
191
|
-
{ locale: 'de-DE' }
|
|
192
|
-
)
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
#### Upsert Many Profiles
|
|
196
|
-
|
|
197
|
-
The `upsertManyProfiles` method returns a `Promise` that resolves with an array of user profiles.
|
|
198
|
-
Each event should have an additional `anonymousId` property set to the associated anonymous ID or
|
|
199
|
-
profile ID.
|
|
200
|
-
|
|
201
|
-
```ts
|
|
202
|
-
const client = new ApiClient({ clientId: 'abc123' })
|
|
203
|
-
const profiles = await client.personalization.upsertManyProfiles(
|
|
204
|
-
{ events: [...]},
|
|
205
131
|
{ locale: 'de-DE' },
|
|
206
132
|
)
|
|
207
133
|
```
|
|
208
134
|
|
|
209
|
-
|
|
135
|
+
Common methods include `getProfile`, `createProfile`, `updateProfile`, `upsertProfile`, and
|
|
136
|
+
`upsertManyProfiles`.
|
|
210
137
|
|
|
211
|
-
Insights API
|
|
212
|
-
`Promise` that resolves to `void` (no value).
|
|
138
|
+
### Insights API
|
|
213
139
|
|
|
214
|
-
|
|
140
|
+
Insights API methods are scoped to `client.insights` and send analytics event batches:
|
|
215
141
|
|
|
216
142
|
```ts
|
|
217
|
-
|
|
218
|
-
await client.analytics.sendBatchEvents([
|
|
143
|
+
await client.insights.sendBatchEvents([
|
|
219
144
|
{
|
|
220
|
-
profile
|
|
221
|
-
events: [
|
|
222
|
-
}
|
|
145
|
+
profile,
|
|
146
|
+
events: [viewEvent],
|
|
147
|
+
},
|
|
223
148
|
])
|
|
224
149
|
```
|
|
225
150
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
The Event Builder is a helper class that assists in constructing valid events for submission to the
|
|
229
|
-
Experience and Insights APIs.
|
|
230
|
-
|
|
231
|
-
### Event Builder Configuration
|
|
232
|
-
|
|
233
|
-
Event Builder configuration options assist in adding contextual data to each event created by a
|
|
234
|
-
builder instance.
|
|
235
|
-
|
|
236
|
-
| Option | Required? | Default | Description |
|
|
237
|
-
| ------------------- | --------- | ------------------------------- | ---------------------------------------------------------------------------------- |
|
|
238
|
-
| `app` | No | `undefined` | The application definition used to attribute events to a specific consumer app |
|
|
239
|
-
| `channel` | Yes | N/A | The channel that identifies where events originate from (e.g. `'web'`, `'mobile'`) |
|
|
240
|
-
| `library` | Yes | N/A | The client library metadata that is attached to all events |
|
|
241
|
-
| `getLocale` | No | `() => 'en-US'` | Function used to resolve the locale for outgoing events |
|
|
242
|
-
| `getPageProperties` | No | `() => DEFAULT_PAGE_PROPERTIES` | Function that returns the current page properties |
|
|
243
|
-
| `getUserAgent` | No | `() => undefined` | Function used to obtain the current user agent string when applicable |
|
|
244
|
-
|
|
245
|
-
The `get*` functions are most useful in stateful environments. Stateless environments should set the
|
|
246
|
-
related data directly via Event Builder method arguments.
|
|
247
|
-
|
|
248
|
-
The `channel` option may contain one of the following values:
|
|
249
|
-
|
|
250
|
-
- `web`
|
|
251
|
-
- `mobile`
|
|
252
|
-
- `server`
|
|
253
|
-
|
|
254
|
-
Configuration method signatures:
|
|
151
|
+
Insights endpoints do not return response data. For last-chance browser lifecycle delivery, pass a
|
|
152
|
+
per-call `beacon` sender that receives the request URL and already serialized body.
|
|
255
153
|
|
|
256
|
-
|
|
257
|
-
- `getPageProperties`:
|
|
154
|
+
### Fetch helpers
|
|
258
155
|
|
|
259
|
-
|
|
260
|
-
() => {
|
|
261
|
-
path: string,
|
|
262
|
-
query: Record<string, string>,
|
|
263
|
-
referrer: string,
|
|
264
|
-
search: string,
|
|
265
|
-
title?: string,
|
|
266
|
-
url: string
|
|
267
|
-
}
|
|
268
|
-
```
|
|
156
|
+
This package also exports fetch helper functions used by SDK layers:
|
|
269
157
|
|
|
270
|
-
|
|
158
|
+
| Helper | Purpose |
|
|
159
|
+
| ---------------------------- | ------------------------------------------------------- |
|
|
160
|
+
| `createProtectedFetchMethod` | Adds timeout and retry protection around a fetch method |
|
|
161
|
+
| `createRetryFetchMethod` | Applies retry policy to retryable responses |
|
|
162
|
+
| `createTimeoutFetchMethod` | Aborts requests after the configured timeout |
|
|
271
163
|
|
|
272
|
-
|
|
164
|
+
Use generated reference docs for helper signatures and callback payloads.
|
|
273
165
|
|
|
274
|
-
|
|
275
|
-
- `buildFlagView`: Builds a component view payload event for a Custom Flag component
|
|
276
|
-
- `buildIdentify`: Builds an identify event payload to associate a user ID with traits
|
|
277
|
-
- `buildPageView`: Builds a page view event payload
|
|
278
|
-
- `buildTrack`: Builds a track event payload for arbitrary user actions
|
|
166
|
+
## Related
|
|
279
167
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
168
|
+
- [API Client generated reference](https://contentful.github.io/optimization/modules/_contentful_optimization-api-client.html) -
|
|
169
|
+
exported API reference
|
|
170
|
+
- [API Schemas](https://github.com/contentful/optimization/blob/optimization-api-client-v1.0.0/packages/universal/api-schemas/README.md) - runtime validation schemas and inferred API types
|
|
171
|
+
- [Optimization Core SDK](https://github.com/contentful/optimization/blob/optimization-api-client-v1.0.0/packages/universal/core-sdk/README.md) - platform-agnostic SDK layer that composes this
|
|
172
|
+
client
|
|
173
|
+
- [Choosing the right SDK](https://contentful.github.io/optimization/documents/Documentation.Guides.choosing-the-right-sdk.html) -
|
|
174
|
+
package selection guidance for application integrations
|