@contentful/optimization-api-client 0.1.0-alpha → 0.1.0-alpha11
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 +70 -95
- 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 +425 -580
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +865 -0
- package/dist/index.d.mts +865 -0
- package/dist/index.d.ts +865 -8
- package/dist/index.mjs +67 -277
- 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 +46 -10
- 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 -142
- 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/v0.1.0-alpha11/contentful-icon.png" width="150">
|
|
4
4
|
</a>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
@@ -10,17 +10,22 @@
|
|
|
10
10
|
|
|
11
11
|
<div align="center">
|
|
12
12
|
|
|
13
|
-
[
|
|
14
|
-
[Contributing](/CONTRIBUTING.md)
|
|
13
|
+
[Guides](https://contentful.github.io/optimization/documents/Guides.html) ·
|
|
14
|
+
[Reference](https://contentful.github.io/optimization) · [Contributing](https://github.com/contentful/optimization/blob/v0.1.0-alpha11/CONTRIBUTING.md)
|
|
15
15
|
|
|
16
16
|
</div>
|
|
17
17
|
|
|
18
|
+
> [!WARNING]
|
|
19
|
+
>
|
|
20
|
+
> The Optimization SDK Suite is pre-release (alpha). Breaking changes may be published at any time.
|
|
21
|
+
|
|
18
22
|
The Contentful Optimization API Client Library provides methods for interfacing with Contentful's
|
|
19
|
-
Experience and Insights
|
|
23
|
+
Experience API and Insights API, which serve its Personalization and Analytics products.
|
|
20
24
|
|
|
21
25
|
> [!NOTE]
|
|
22
26
|
>
|
|
23
|
-
>
|
|
27
|
+
> The Experience API and Insights API are separate today, and this client provides a unified SDK
|
|
28
|
+
> surface for both APIs.
|
|
24
29
|
|
|
25
30
|
<details>
|
|
26
31
|
<summary>Table of Contents</summary>
|
|
@@ -30,8 +35,8 @@ Experience and Insights APIs, which serve its Personalization and Analytics prod
|
|
|
30
35
|
- [Configuration](#configuration)
|
|
31
36
|
- [Top-level Configuration Options](#top-level-configuration-options)
|
|
32
37
|
- [Fetch Options](#fetch-options)
|
|
33
|
-
- [
|
|
34
|
-
- [
|
|
38
|
+
- [Insights API Options](#insights-api-options)
|
|
39
|
+
- [Experience API Options](#experience-api-options)
|
|
35
40
|
- [Working With the APIs](#working-with-the-apis)
|
|
36
41
|
- [Experience API](#experience-api)
|
|
37
42
|
- [Get Profile data](#get-profile-data)
|
|
@@ -41,9 +46,7 @@ Experience and Insights APIs, which serve its Personalization and Analytics prod
|
|
|
41
46
|
- [Upsert Many Profiles](#upsert-many-profiles)
|
|
42
47
|
- [Insights API](#insights-api)
|
|
43
48
|
- [Send Batch Events](#send-batch-events)
|
|
44
|
-
- [Event
|
|
45
|
-
- [Event Builder Configuration](#event-builder-configuration)
|
|
46
|
-
- [Event Builder Configured Methods](#event-builder-configured-methods)
|
|
49
|
+
- [Event Construction](#event-construction)
|
|
47
50
|
|
|
48
51
|
<!-- mtoc-end -->
|
|
49
52
|
</details>
|
|
@@ -72,20 +75,20 @@ const client = new ApiClient({ clientId: 'abc123' })
|
|
|
72
75
|
|
|
73
76
|
### Top-level Configuration Options
|
|
74
77
|
|
|
75
|
-
| Option
|
|
76
|
-
|
|
|
77
|
-
| `
|
|
78
|
-
| `clientId`
|
|
79
|
-
| `environment`
|
|
80
|
-
| `fetchOptions`
|
|
81
|
-
| `
|
|
78
|
+
| Option | Required? | Default | Description |
|
|
79
|
+
| -------------- | --------- | ---------------------------- | ----------------------------------------------------------- |
|
|
80
|
+
| `experience` | No | See "Experience API Options" | Configuration specific to the Experience API |
|
|
81
|
+
| `clientId` | Yes | N/A | Shared API key for Experience API and Insights API requests |
|
|
82
|
+
| `environment` | No | `'main'` | The environment identifier |
|
|
83
|
+
| `fetchOptions` | No | See "Fetch Options" | Configuration for Fetch timeout and retry functionality |
|
|
84
|
+
| `insights` | No | See "Insights API Options" | Configuration specific to the Insights API |
|
|
82
85
|
|
|
83
86
|
### Fetch Options
|
|
84
87
|
|
|
85
88
|
Fetch options allow for configuration of both a Fetch API-compatible fetch method and the
|
|
86
|
-
retry/timeout logic integrated into
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
retry/timeout logic integrated into this API client. Specify the `fetchMethod` when the host
|
|
90
|
+
application environment does not offer a `fetch` method that is compatible with the standard Fetch
|
|
91
|
+
API in its global scope.
|
|
89
92
|
|
|
90
93
|
| Option | Required? | Default | Description |
|
|
91
94
|
| ------------------ | --------- | ----------- | --------------------------------------------------------------------- |
|
|
@@ -101,7 +104,16 @@ Configuration method signatures:
|
|
|
101
104
|
- `fetchMethod`: `(url: string \| URL, init: RequestInit) => Promise<Response>`
|
|
102
105
|
- `onFailedAttempt` and `onRequestTimeout`: `(options: FetchMethodCallbackOptions) => void`
|
|
103
106
|
|
|
104
|
-
|
|
107
|
+
> [!NOTE]
|
|
108
|
+
>
|
|
109
|
+
> Retry behavior is intentionally fixed to HTTP `503` responses (`Service Unavailable`) for the
|
|
110
|
+
> default SDK transport policy. This matches current Experience API and Insights API expectations:
|
|
111
|
+
> `503` is treated as the transient availability signal, while other response classes are handled by
|
|
112
|
+
> caller logic and are intentionally not retried by default. Treat this as deliberate contract
|
|
113
|
+
> behavior, not a transport gap; broaden retry status handling only with an explicit API contract
|
|
114
|
+
> change.
|
|
115
|
+
|
|
116
|
+
### Insights API Options
|
|
105
117
|
|
|
106
118
|
| Option | Required? | Default | Description |
|
|
107
119
|
| --------------- | --------- | ------------------------------------------ | ------------------------------------------------------------------------ |
|
|
@@ -112,7 +124,7 @@ Configuration method signatures:
|
|
|
112
124
|
|
|
113
125
|
- `beaconHandler`: `(url: string | URL, data: BatchInsightsEventArray) => boolean`
|
|
114
126
|
|
|
115
|
-
###
|
|
127
|
+
### Experience API Options
|
|
116
128
|
|
|
117
129
|
| Option | Required? | Default | Description |
|
|
118
130
|
| ----------------- | --------- | ------------------------------------- | ------------------------------------------------------------------- |
|
|
@@ -131,22 +143,22 @@ Configuration method signatures:
|
|
|
131
143
|
|
|
132
144
|
### Experience API
|
|
133
145
|
|
|
134
|
-
Experience API methods are scoped to the client's `
|
|
135
|
-
|
|
146
|
+
Experience API methods are scoped to the client's `experience` member. All singular Experience API
|
|
147
|
+
methods return a `Promise` that resolves with the following data:
|
|
136
148
|
|
|
137
149
|
```json
|
|
138
150
|
{
|
|
139
151
|
"profile": {
|
|
140
152
|
/* User profile data */
|
|
141
153
|
},
|
|
142
|
-
"
|
|
154
|
+
"selectedOptimizations": [
|
|
143
155
|
{
|
|
144
|
-
/*
|
|
156
|
+
/* Optimization/Experience API configuration for the associated profile */
|
|
145
157
|
}
|
|
146
158
|
],
|
|
147
159
|
"changes": [
|
|
148
160
|
{
|
|
149
|
-
/*
|
|
161
|
+
/* Custom Flag changes associated with the evaluated profile */
|
|
150
162
|
}
|
|
151
163
|
]
|
|
152
164
|
}
|
|
@@ -156,21 +168,21 @@ personalization methods return a `Promise` that resolves with the following data
|
|
|
156
168
|
|
|
157
169
|
```ts
|
|
158
170
|
const client = new ApiClient({ clientId: 'abc123' })
|
|
159
|
-
const { profile } = await client.
|
|
171
|
+
const { profile } = await client.experience.getProfile('profile-123', { locale: 'de-DE' })
|
|
160
172
|
```
|
|
161
173
|
|
|
162
174
|
#### Create a New Profile
|
|
163
175
|
|
|
164
176
|
```ts
|
|
165
177
|
const client = new ApiClient({ clientId: 'abc123' })
|
|
166
|
-
const { profile } = await client.
|
|
178
|
+
const { profile } = await client.experience.createProfile({ events: [...] }, { locale: 'de-DE' })
|
|
167
179
|
```
|
|
168
180
|
|
|
169
181
|
#### Update an Existing Profile
|
|
170
182
|
|
|
171
183
|
```ts
|
|
172
184
|
const client = new ApiClient({ clientId: 'abc123' })
|
|
173
|
-
const { profile } = await client.
|
|
185
|
+
const { profile } = await client.experience.updateProfile(
|
|
174
186
|
{
|
|
175
187
|
profileId: 'profile-123',
|
|
176
188
|
events: [...],
|
|
@@ -183,7 +195,7 @@ const { profile } = await client.personalization.updateProfile(
|
|
|
183
195
|
|
|
184
196
|
```ts
|
|
185
197
|
const client = new ApiClient({ clientId: 'abc123' })
|
|
186
|
-
const { profile } = await client.
|
|
198
|
+
const { profile } = await client.experience.upsertProfile(
|
|
187
199
|
{
|
|
188
200
|
profileId,
|
|
189
201
|
events: [...],
|
|
@@ -195,88 +207,51 @@ const { profile } = await client.personalization.upsertProfile(
|
|
|
195
207
|
#### Upsert Many Profiles
|
|
196
208
|
|
|
197
209
|
The `upsertManyProfiles` method returns a `Promise` that resolves with an array of user profiles.
|
|
198
|
-
|
|
199
|
-
profile ID.
|
|
210
|
+
The `events` array must contain at least one event. Each event should have an additional
|
|
211
|
+
`anonymousId` property set to the associated anonymous ID or profile ID.
|
|
200
212
|
|
|
201
213
|
```ts
|
|
202
214
|
const client = new ApiClient({ clientId: 'abc123' })
|
|
203
|
-
const profiles = await client.
|
|
204
|
-
{
|
|
215
|
+
const profiles = await client.experience.upsertManyProfiles(
|
|
216
|
+
{
|
|
217
|
+
events: [
|
|
218
|
+
{
|
|
219
|
+
anonymousId: 'anon-123',
|
|
220
|
+
// valid Experience API event payload fields
|
|
221
|
+
},
|
|
222
|
+
],
|
|
223
|
+
},
|
|
205
224
|
{ locale: 'de-DE' },
|
|
206
225
|
)
|
|
207
226
|
```
|
|
208
227
|
|
|
209
228
|
### Insights API
|
|
210
229
|
|
|
211
|
-
Insights API methods are scoped to the client's `
|
|
212
|
-
`Promise` that resolves to `
|
|
230
|
+
Insights API methods are scoped to the client's `insights` member. The batch send method returns a
|
|
231
|
+
`Promise` that resolves to `boolean`.
|
|
213
232
|
|
|
214
233
|
#### Send Batch Events
|
|
215
234
|
|
|
216
235
|
```ts
|
|
217
236
|
const client = new ApiClient({ clientId: 'abc123' })
|
|
218
|
-
await client.
|
|
237
|
+
await client.insights.sendBatchEvents([
|
|
219
238
|
{
|
|
220
239
|
profile: { id: 'abc-123', ... },
|
|
221
|
-
events: [
|
|
240
|
+
events: [
|
|
241
|
+
{
|
|
242
|
+
type: 'component',
|
|
243
|
+
componentId: 'hero-banner',
|
|
244
|
+
componentType: 'Entry',
|
|
245
|
+
variantIndex: 0,
|
|
246
|
+
...,
|
|
247
|
+
},
|
|
248
|
+
],
|
|
222
249
|
}
|
|
223
250
|
])
|
|
224
251
|
```
|
|
225
252
|
|
|
226
|
-
## Event
|
|
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:
|
|
255
|
-
|
|
256
|
-
- `getLocale`: `() => string | undefined`
|
|
257
|
-
- `getPageProperties`:
|
|
258
|
-
|
|
259
|
-
```ts
|
|
260
|
-
() => {
|
|
261
|
-
path: string,
|
|
262
|
-
query: Record<string, string>,
|
|
263
|
-
referrer: string,
|
|
264
|
-
search: string,
|
|
265
|
-
title?: string,
|
|
266
|
-
url: string
|
|
267
|
-
}
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
- `getUserAgent`: `() => string | undefined`
|
|
271
|
-
|
|
272
|
-
#### Event Builder Configured Methods
|
|
273
|
-
|
|
274
|
-
- `buildComponentView`: Builds a component view event payload for a Contentful entry-based component
|
|
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
|
|
253
|
+
## Event Construction
|
|
279
254
|
|
|
280
|
-
|
|
281
|
-
[
|
|
282
|
-
|
|
255
|
+
Event-construction helpers (`EventBuilder`) are part of
|
|
256
|
+
[`@contentful/optimization-core`](https://github.com/contentful/optimization/blob/v0.1.0-alpha11/packages/universal/core-sdk/README.md) and environment SDKs that build on top of
|
|
257
|
+
it. This package focuses on API transport and request/response validation.
|
package/dist/199.mjs
ADDED
package/dist/649.mjs
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
class LogSink {
|
|
2
|
+
}
|
|
3
|
+
const logger_LogSink = LogSink;
|
|
4
|
+
class Logger {
|
|
5
|
+
name = '@contentful/optimization';
|
|
6
|
+
PREFIX_PARTS = [
|
|
7
|
+
'Ctfl',
|
|
8
|
+
'O10n'
|
|
9
|
+
];
|
|
10
|
+
DELIMITER = ':';
|
|
11
|
+
sinks = [];
|
|
12
|
+
assembleLocationPrefix(logLocation) {
|
|
13
|
+
return `[${[
|
|
14
|
+
...this.PREFIX_PARTS,
|
|
15
|
+
logLocation
|
|
16
|
+
].join(this.DELIMITER)}]`;
|
|
17
|
+
}
|
|
18
|
+
addSink(sink) {
|
|
19
|
+
this.sinks = [
|
|
20
|
+
...this.sinks.filter((existingSink)=>existingSink.name !== sink.name),
|
|
21
|
+
sink
|
|
22
|
+
];
|
|
23
|
+
}
|
|
24
|
+
removeSink(name) {
|
|
25
|
+
this.sinks = this.sinks.filter((sink)=>sink.name !== name);
|
|
26
|
+
}
|
|
27
|
+
removeSinks() {
|
|
28
|
+
this.sinks = [];
|
|
29
|
+
}
|
|
30
|
+
debug(logLocation, message, ...args) {
|
|
31
|
+
this.emit('debug', logLocation, message, ...args);
|
|
32
|
+
}
|
|
33
|
+
info(logLocation, message, ...args) {
|
|
34
|
+
this.emit('info', logLocation, message, ...args);
|
|
35
|
+
}
|
|
36
|
+
log(logLocation, message, ...args) {
|
|
37
|
+
this.emit('log', logLocation, message, ...args);
|
|
38
|
+
}
|
|
39
|
+
warn(logLocation, message, ...args) {
|
|
40
|
+
this.emit('warn', logLocation, message, ...args);
|
|
41
|
+
}
|
|
42
|
+
error(logLocation, message, ...args) {
|
|
43
|
+
this.emit('error', logLocation, message, ...args);
|
|
44
|
+
}
|
|
45
|
+
fatal(logLocation, message, ...args) {
|
|
46
|
+
this.emit('fatal', logLocation, message, ...args);
|
|
47
|
+
}
|
|
48
|
+
emit(level, logLocation, message, ...args) {
|
|
49
|
+
this.onLogEvent({
|
|
50
|
+
name: this.name,
|
|
51
|
+
level,
|
|
52
|
+
messages: [
|
|
53
|
+
`${this.assembleLocationPrefix(logLocation)} ${String(message)}`,
|
|
54
|
+
...args
|
|
55
|
+
]
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
onLogEvent(event) {
|
|
59
|
+
this.sinks.forEach((sink)=>{
|
|
60
|
+
sink.ingest(event);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const logger = new Logger();
|
|
65
|
+
function createScopedLogger(location) {
|
|
66
|
+
return {
|
|
67
|
+
debug: (message, ...args)=>{
|
|
68
|
+
logger.debug(location, message, ...args);
|
|
69
|
+
},
|
|
70
|
+
info: (message, ...args)=>{
|
|
71
|
+
logger.info(location, message, ...args);
|
|
72
|
+
},
|
|
73
|
+
log: (message, ...args)=>{
|
|
74
|
+
logger.log(location, message, ...args);
|
|
75
|
+
},
|
|
76
|
+
warn: (message, ...args)=>{
|
|
77
|
+
logger.warn(location, message, ...args);
|
|
78
|
+
},
|
|
79
|
+
error: (message, ...args)=>{
|
|
80
|
+
logger.error(location, message, ...args);
|
|
81
|
+
},
|
|
82
|
+
fatal: (message, ...args)=>{
|
|
83
|
+
logger.fatal(location, message, ...args);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const logLevelSeverity = {
|
|
88
|
+
fatal: 60,
|
|
89
|
+
error: 50,
|
|
90
|
+
warn: 40,
|
|
91
|
+
info: 30,
|
|
92
|
+
debug: 20,
|
|
93
|
+
log: 10
|
|
94
|
+
};
|
|
95
|
+
const consoleMap = {
|
|
96
|
+
debug: (...args)=>{
|
|
97
|
+
console.debug(...args);
|
|
98
|
+
},
|
|
99
|
+
info: (...args)=>{
|
|
100
|
+
console.info(...args);
|
|
101
|
+
},
|
|
102
|
+
log: (...args)=>{
|
|
103
|
+
console.log(...args);
|
|
104
|
+
},
|
|
105
|
+
warn: (...args)=>{
|
|
106
|
+
console.warn(...args);
|
|
107
|
+
},
|
|
108
|
+
error: (...args)=>{
|
|
109
|
+
console.error(...args);
|
|
110
|
+
},
|
|
111
|
+
fatal: (...args)=>{
|
|
112
|
+
console.error(...args);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
class ConsoleLogSink extends logger_LogSink {
|
|
116
|
+
name = 'ConsoleLogSink';
|
|
117
|
+
verbosity;
|
|
118
|
+
constructor(verbosity){
|
|
119
|
+
super();
|
|
120
|
+
this.verbosity = verbosity ?? 'error';
|
|
121
|
+
}
|
|
122
|
+
ingest(event) {
|
|
123
|
+
if (logLevelSeverity[event.level] < logLevelSeverity[this.verbosity]) return;
|
|
124
|
+
consoleMap[event.level](...event.messages);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const lib_logger = Logger;
|
|
128
|
+
export default lib_logger;
|
|
129
|
+
export { ConsoleLogSink, Logger, createScopedLogger, logLevelSeverity, logger, logger_LogSink as LogSink };
|
|
130
|
+
|
|
131
|
+
//# sourceMappingURL=649.mjs.map
|
package/dist/649.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"649.mjs","sources":["../src/lib/logger/LogSink.ts","../src/lib/logger/Logger.ts","../src/lib/logger/logging.ts","../src/lib/logger/ConsoleLogSink.ts","../src/lib/logger/index.ts"],"sourcesContent":["import type { LogEvent } from './logging'\n\n/**\n * Abstract base class for log sinks that receive and process log events.\n *\n * @example\n * ```typescript\n * class MyCustomSink extends LogSink {\n * name = 'MyCustomSink'\n *\n * ingest(event: LogEvent): void {\n * // process the event\n * }\n * }\n * ```\n *\n * @public\n */\nabstract class LogSink {\n /** Display name used to identify this sink for addition and removal. */\n abstract name: string\n\n /**\n * Processes an incoming log event.\n *\n * @param event - The log event to process.\n * @returns Nothing.\n */\n abstract ingest(event: LogEvent): void\n}\n\nexport default LogSink\n","import type LogSink from './LogSink'\nimport type { LogEvent, LogLevels } from './logging'\n\n/**\n * Central logger that routes log events through registered {@link LogSink} instances.\n *\n * @example\n * ```typescript\n * import { logger } from '@contentful/optimization-api-client/logger'\n *\n * logger.info('MyModule', 'Application started')\n * ```\n *\n * @public\n */\nexport class Logger {\n /** The logger's identifier, used as the event scope name. */\n readonly name = '@contentful/optimization'\n\n private readonly PREFIX_PARTS = ['Ctfl', 'O10n']\n private readonly DELIMITER = ':'\n private sinks: LogSink[] = []\n\n private assembleLocationPrefix(logLocation: string): string {\n return `[${[...this.PREFIX_PARTS, logLocation].join(this.DELIMITER)}]`\n }\n\n /**\n * Registers a log sink. If a sink with the same name already exists, it is replaced.\n *\n * @param sink - The {@link LogSink} instance to register.\n * @returns Nothing.\n *\n * @example\n * ```typescript\n * import { logger, ConsoleLogSink } from '@contentful/optimization-api-client/logger'\n *\n * logger.addSink(new ConsoleLogSink('debug'))\n * ```\n */\n public addSink(sink: LogSink): void {\n this.sinks = [...this.sinks.filter((existingSink) => existingSink.name !== sink.name), sink]\n }\n\n /**\n * Removes a registered sink by name.\n *\n * @param name - The name of the sink to remove.\n * @returns Nothing.\n *\n * @example\n * ```typescript\n * logger.removeSink('ConsoleLogSink')\n * ```\n */\n public removeSink(name: string): void {\n this.sinks = this.sinks.filter((sink) => sink.name !== name)\n }\n\n /**\n * Removes all registered sinks.\n *\n * @returns Nothing.\n *\n * @example\n * ```typescript\n * logger.removeSinks()\n * ```\n */\n public removeSinks(): void {\n this.sinks = []\n }\n\n /**\n * Logs a message at the debug level.\n *\n * @param logLocation - The module or component identifier.\n * @param message - The log message.\n * @param args - Additional arguments forwarded in the log event.\n * @returns Nothing.\n *\n * @example\n * ```typescript\n * logger.debug('MyModule', 'Debugging value', someVariable)\n * ```\n */\n public debug(logLocation: string, message: string, ...args: unknown[]): void {\n this.emit('debug', logLocation, message, ...args)\n }\n\n /**\n * Logs a message at the info level.\n *\n * @param logLocation - The module or component identifier.\n * @param message - The log message.\n * @param args - Additional arguments forwarded in the log event.\n * @returns Nothing.\n *\n * @example\n * ```typescript\n * logger.info('MyModule', 'Operation completed')\n * ```\n */\n public info(logLocation: string, message: string, ...args: unknown[]): void {\n this.emit('info', logLocation, message, ...args)\n }\n\n /**\n * Logs a message at the log level.\n *\n * @param logLocation - The module or component identifier.\n * @param message - The log message.\n * @param args - Additional arguments forwarded in the log event.\n * @returns Nothing.\n *\n * @example\n * ```typescript\n * logger.log('MyModule', 'General log entry')\n * ```\n */\n public log(logLocation: string, message: string, ...args: unknown[]): void {\n this.emit('log', logLocation, message, ...args)\n }\n\n /**\n * Logs a message at the warn level.\n *\n * @param logLocation - The module or component identifier.\n * @param message - The log message.\n * @param args - Additional arguments forwarded in the log event.\n * @returns Nothing.\n *\n * @example\n * ```typescript\n * logger.warn('MyModule', 'Deprecated method called')\n * ```\n */\n public warn(logLocation: string, message: string, ...args: unknown[]): void {\n this.emit('warn', logLocation, message, ...args)\n }\n\n /**\n * Logs a message at the error level.\n *\n * @param logLocation - The module or component identifier.\n * @param message - The log message or Error object.\n * @param args - Additional arguments forwarded in the log event.\n * @returns Nothing.\n *\n * @example\n * ```typescript\n * logger.error('MyModule', new Error('Something failed'))\n * ```\n */\n public error(logLocation: string, message: string | Error, ...args: unknown[]): void {\n this.emit('error', logLocation, message, ...args)\n }\n\n /**\n * Logs a message at the fatal level.\n *\n * @param logLocation - The module or component identifier.\n * @param message - The log message or Error object.\n * @param args - Additional arguments forwarded in the log event.\n * @returns Nothing.\n *\n * @example\n * ```typescript\n * logger.fatal('MyModule', new Error('Unrecoverable failure'))\n * ```\n */\n public fatal(logLocation: string, message: string | Error, ...args: unknown[]): void {\n this.emit('fatal', logLocation, message, ...args)\n }\n\n private emit(\n level: LogLevels,\n logLocation: string,\n message: string | Error,\n ...args: unknown[]\n ): void {\n this.onLogEvent({\n name: this.name,\n level,\n messages: [`${this.assembleLocationPrefix(logLocation)} ${String(message)}`, ...args],\n })\n }\n\n private onLogEvent(event: LogEvent): void {\n this.sinks.forEach((sink) => {\n sink.ingest(event)\n })\n }\n}\n\n/**\n * Shared singleton {@link Logger} instance used across the SDK.\n *\n * @public\n */\nexport const logger = new Logger()\n\n/**\n * A location-scoped logger interface whose methods omit the `logLocation` parameter.\n *\n * @public\n */\nexport interface ScopedLogger {\n /** Logs at debug level. */\n debug: (message: string, ...args: unknown[]) => void\n /** Logs at info level. */\n info: (message: string, ...args: unknown[]) => void\n /** Logs at log level. */\n log: (message: string, ...args: unknown[]) => void\n /** Logs at warn level. */\n warn: (message: string, ...args: unknown[]) => void\n /** Logs at error level. */\n error: (message: string | Error, ...args: unknown[]) => void\n /** Logs at fatal level. */\n fatal: (message: string | Error, ...args: unknown[]) => void\n}\n\n/**\n * Creates a {@link ScopedLogger} that automatically prepends the given location to every log call.\n *\n * @param location - The module or component identifier to prepend.\n * @returns A {@link ScopedLogger} bound to the specified location.\n *\n * @example\n * ```typescript\n * import { createScopedLogger } from '@contentful/optimization-api-client/logger'\n *\n * const log = createScopedLogger('MyModule')\n * log.info('Initialization complete')\n * ```\n *\n * @public\n */\nexport function createScopedLogger(location: string): ScopedLogger {\n return {\n debug: (message: string, ...args: unknown[]) => {\n logger.debug(location, message, ...args)\n },\n info: (message: string, ...args: unknown[]) => {\n logger.info(location, message, ...args)\n },\n log: (message: string, ...args: unknown[]) => {\n logger.log(location, message, ...args)\n },\n warn: (message: string, ...args: unknown[]) => {\n logger.warn(location, message, ...args)\n },\n error: (message: string | Error, ...args: unknown[]) => {\n logger.error(location, message, ...args)\n },\n fatal: (message: string | Error, ...args: unknown[]) => {\n logger.fatal(location, message, ...args)\n },\n }\n}\n","/**\n * Supported log levels ordered from highest to lowest severity.\n *\n * @public\n */\nexport type LogLevels = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'log'\n\n/**\n * A log event emitted by the logger package.\n *\n * @public\n */\nexport interface LogEvent {\n /** Logger scope name. */\n name: string\n /** Event severity level. */\n level: LogLevels\n /** Event payload, where the first entry is the formatted message. */\n messages: unknown[]\n /** Optional additional context attached by sinks or middleware. */\n [other: string]: unknown\n}\n\n/**\n * Numeric severity map used for log-level threshold comparisons.\n *\n * @public\n */\nexport const logLevelSeverity: Readonly<Record<LogLevels, number>> = {\n fatal: 60,\n error: 50,\n warn: 40,\n info: 30,\n debug: 20,\n log: 10,\n}\n","/* eslint-disable no-console -- using console */\nimport { logLevelSeverity, type LogEvent, type LogLevels } from './logging'\nimport LogSink from './LogSink'\n\nconst consoleMap = {\n debug: (...args: unknown[]) => {\n console.debug(...args)\n },\n info: (...args: unknown[]) => {\n console.info(...args)\n },\n log: (...args: unknown[]) => {\n console.log(...args)\n },\n warn: (...args: unknown[]) => {\n console.warn(...args)\n },\n error: (...args: unknown[]) => {\n console.error(...args)\n },\n fatal: (...args: unknown[]) => {\n console.error(...args)\n },\n}\n\n/**\n * A {@link LogSink} that writes log events to the browser or Node.js console,\n * filtering by a configurable verbosity threshold.\n *\n * @example\n * ```typescript\n * import { logger, ConsoleLogSink } from '@contentful/optimization-api-client/logger'\n *\n * logger.addSink(new ConsoleLogSink('debug'))\n * ```\n *\n * @public\n */\nexport class ConsoleLogSink extends LogSink {\n /** Identifies this sink when registered with the {@link Logger}. */\n public name = 'ConsoleLogSink'\n\n /**\n * Minimum log level required for events to be output.\n *\n * @defaultValue 'error'\n */\n readonly verbosity: LogLevels\n\n /**\n * Creates a new ConsoleLogSink.\n *\n * @param verbosity - Minimum log level to output.\n */\n constructor(verbosity?: LogLevels) {\n super()\n\n this.verbosity = verbosity ?? 'error'\n }\n\n /**\n * Writes a log event to the console if its level meets the verbosity threshold.\n *\n * @param event - The log event to process.\n * @returns Nothing.\n */\n ingest(event: LogEvent): void {\n if (logLevelSeverity[event.level] < logLevelSeverity[this.verbosity]) return\n\n consoleMap[event.level](...event.messages)\n }\n}\n","import LogSink from './LogSink'\nimport { Logger } from './Logger'\n\nexport * from './ConsoleLogSink'\nexport * from './LogSink'\nexport * from './Logger'\nexport * from './logging'\n\nexport { LogSink }\nexport default Logger\n"],"names":["LogSink","Logger","logLocation","sink","existingSink","name","message","args","level","String","event","logger","createScopedLogger","location","logLevelSeverity","consoleMap","console","ConsoleLogSink","verbosity"],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_modules__ = {
|
|
3
|
+
"@contentful/optimization-api-schemas" (module) {
|
|
4
|
+
module.exports = require("@contentful/optimization-api-schemas");
|
|
5
|
+
}
|
|
6
|
+
};
|
|
7
|
+
var __webpack_module_cache__ = {};
|
|
8
|
+
function __webpack_require__(moduleId) {
|
|
9
|
+
var cachedModule = __webpack_module_cache__[moduleId];
|
|
10
|
+
if (void 0 !== cachedModule) return cachedModule.exports;
|
|
11
|
+
var module = __webpack_module_cache__[moduleId] = {
|
|
12
|
+
exports: {}
|
|
13
|
+
};
|
|
14
|
+
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
15
|
+
return module.exports;
|
|
16
|
+
}
|
|
17
|
+
(()=>{
|
|
18
|
+
__webpack_require__.n = (module)=>{
|
|
19
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
20
|
+
__webpack_require__.d(getter, {
|
|
21
|
+
a: getter
|
|
22
|
+
});
|
|
23
|
+
return getter;
|
|
24
|
+
};
|
|
25
|
+
})();
|
|
26
|
+
(()=>{
|
|
27
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
28
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
get: definition[key]
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
})();
|
|
34
|
+
(()=>{
|
|
35
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
36
|
+
})();
|
|
37
|
+
(()=>{
|
|
38
|
+
__webpack_require__.r = (exports1)=>{
|
|
39
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
40
|
+
value: 'Module'
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
43
|
+
value: true
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
})();
|
|
47
|
+
var __webpack_exports__ = {};
|
|
48
|
+
(()=>{
|
|
49
|
+
__webpack_require__.r(__webpack_exports__);
|
|
50
|
+
var _contentful_optimization_api_schemas__rspack_import_0 = __webpack_require__("@contentful/optimization-api-schemas");
|
|
51
|
+
var __rspack_reexport = {};
|
|
52
|
+
for(const __rspack_import_key in _contentful_optimization_api_schemas__rspack_import_0)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_contentful_optimization_api_schemas__rspack_import_0[__rspack_import_key];
|
|
53
|
+
__webpack_require__.d(__webpack_exports__, __rspack_reexport);
|
|
54
|
+
})();
|
|
55
|
+
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
56
|
+
Object.defineProperty(exports, '__esModule', {
|
|
57
|
+
value: true
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
//# sourceMappingURL=api-schemas.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-schemas.cjs","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol"],"mappings":";;;;;;;;;;;;;;;;;IACAA,oBAAoB,CAAC,GAAG,CAACC;QACxB,IAAIC,SAASD,UAAUA,OAAO,UAAU,GACvC,IAAOA,MAAM,CAAC,UAAU,GACxB,IAAOA;QACRD,oBAAoB,CAAC,CAACE,QAAQ;YAAE,GAAGA;QAAO;QAC1C,OAAOA;IACR;;;ICPAF,oBAAoB,CAAC,GAAG,CAAC,UAASG;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGH,oBAAoB,CAAC,CAACG,YAAYC,QAAQ,CAACJ,oBAAoB,CAAC,CAAC,UAASI,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAJ,oBAAoB,CAAC,GAAG,CAACM,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFP,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,MAAlB,OAAOQ,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D"}
|