@contentful/optimization-api-client 0.1.0-alpha
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/LICENSE +21 -0
- package/README.md +282 -0
- package/dist/ApiClient.d.ts +74 -0
- package/dist/ApiClient.d.ts.map +1 -0
- package/dist/ApiClient.js +61 -0
- package/dist/ApiClient.js.map +1 -0
- package/dist/ApiClientBase.d.ts +113 -0
- package/dist/ApiClientBase.d.ts.map +1 -0
- package/dist/ApiClientBase.js +94 -0
- package/dist/ApiClientBase.js.map +1 -0
- package/dist/builders/EventBuilder.d.ts +589 -0
- package/dist/builders/EventBuilder.d.ts.map +1 -0
- package/dist/builders/EventBuilder.js +349 -0
- package/dist/builders/EventBuilder.js.map +1 -0
- package/dist/builders/index.d.ts +3 -0
- package/dist/builders/index.d.ts.map +1 -0
- package/dist/builders/index.js +3 -0
- package/dist/builders/index.js.map +1 -0
- package/dist/experience/ExperienceApiClient.d.ts +267 -0
- package/dist/experience/ExperienceApiClient.d.ts.map +1 -0
- package/dist/experience/ExperienceApiClient.js +324 -0
- package/dist/experience/ExperienceApiClient.js.map +1 -0
- package/dist/experience/index.d.ts +4 -0
- package/dist/experience/index.d.ts.map +1 -0
- package/dist/experience/index.js +4 -0
- package/dist/experience/index.js.map +1 -0
- package/dist/fetch/Fetch.d.ts +96 -0
- package/dist/fetch/Fetch.d.ts.map +1 -0
- package/dist/fetch/Fetch.js +27 -0
- package/dist/fetch/Fetch.js.map +1 -0
- package/dist/fetch/createProtectedFetchMethod.d.ts +40 -0
- package/dist/fetch/createProtectedFetchMethod.d.ts.map +1 -0
- package/dist/fetch/createProtectedFetchMethod.js +53 -0
- package/dist/fetch/createProtectedFetchMethod.js.map +1 -0
- package/dist/fetch/createRetryFetchMethod.d.ts +60 -0
- package/dist/fetch/createRetryFetchMethod.d.ts.map +1 -0
- package/dist/fetch/createRetryFetchMethod.js +138 -0
- package/dist/fetch/createRetryFetchMethod.js.map +1 -0
- package/dist/fetch/createTimeoutFetchMethod.d.ts +51 -0
- package/dist/fetch/createTimeoutFetchMethod.d.ts.map +1 -0
- package/dist/fetch/createTimeoutFetchMethod.js +51 -0
- package/dist/fetch/createTimeoutFetchMethod.js.map +1 -0
- package/dist/fetch/index.d.ts +7 -0
- package/dist/fetch/index.d.ts.map +1 -0
- package/dist/fetch/index.js +7 -0
- package/dist/fetch/index.js.map +1 -0
- package/dist/index.cjs +708 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +583 -0
- package/dist/index.mjs.map +1 -0
- package/dist/insights/InsightsApiClient.d.ts +130 -0
- package/dist/insights/InsightsApiClient.d.ts.map +1 -0
- package/dist/insights/InsightsApiClient.js +142 -0
- package/dist/insights/InsightsApiClient.js.map +1 -0
- package/dist/insights/index.d.ts +4 -0
- package/dist/insights/index.d.ts.map +1 -0
- package/dist/insights/index.js +4 -0
- package/dist/insights/index.js.map +1 -0
- package/package.json +27 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,708 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_modules__ = {
|
|
3
|
+
"./src/ApiClient.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
4
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
5
|
+
A: ()=>ApiClient
|
|
6
|
+
});
|
|
7
|
+
var _experience__rspack_import_0 = __webpack_require__("./src/experience/index.ts");
|
|
8
|
+
var _insights__rspack_import_1 = __webpack_require__("./src/insights/index.ts");
|
|
9
|
+
class ApiClient {
|
|
10
|
+
config;
|
|
11
|
+
experience;
|
|
12
|
+
insights;
|
|
13
|
+
constructor(config){
|
|
14
|
+
const { personalization, analytics, ...apiConfig } = config;
|
|
15
|
+
this.config = apiConfig;
|
|
16
|
+
this.experience = new _experience__rspack_import_0.A({
|
|
17
|
+
...apiConfig,
|
|
18
|
+
...personalization
|
|
19
|
+
});
|
|
20
|
+
this.insights = new _insights__rspack_import_1.A({
|
|
21
|
+
...apiConfig,
|
|
22
|
+
...analytics
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"./src/ApiClientBase.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
28
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
29
|
+
A: ()=>src_ApiClientBase
|
|
30
|
+
});
|
|
31
|
+
var dist = __webpack_require__("../../lib/logger/dist/index.mjs");
|
|
32
|
+
const external_p_retry_namespaceObject = require("p-retry");
|
|
33
|
+
var external_p_retry_default = /*#__PURE__*/ __webpack_require__.n(external_p_retry_namespaceObject);
|
|
34
|
+
const logger = (0, dist.zP)('ApiClient:Retry');
|
|
35
|
+
const DEFAULT_INTERVAL_TIMEOUT = 0;
|
|
36
|
+
const DEFAULT_RETRY_COUNT = 1;
|
|
37
|
+
const RETRY_RESPONSE_STATUS = 503;
|
|
38
|
+
const HTTP_ERROR_RESPONSE_STATUS = 500;
|
|
39
|
+
class HttpError extends Error {
|
|
40
|
+
status;
|
|
41
|
+
constructor(message, status = HTTP_ERROR_RESPONSE_STATUS){
|
|
42
|
+
super(message);
|
|
43
|
+
Object.setPrototypeOf(this, HttpError.prototype);
|
|
44
|
+
this.status = status;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function createRetryFetchCallback({ apiName = 'Optimization', controller, fetchMethod = fetch, init, url }) {
|
|
48
|
+
return async ()=>{
|
|
49
|
+
try {
|
|
50
|
+
const response = await fetchMethod(url, init);
|
|
51
|
+
if (response.status === RETRY_RESPONSE_STATUS) throw new HttpError(`${apiName} API request to "${url.toString()}" failed with status: "[${response.status}] ${response.statusText}".`, RETRY_RESPONSE_STATUS);
|
|
52
|
+
if (!response.ok) {
|
|
53
|
+
const httpError = new Error(`Request to "${url.toString()}" failed with status: [${response.status}] ${response.statusText} - traceparent: ${response.headers.get('traceparent')}`);
|
|
54
|
+
logger.error('Request failed with non-OK status:', httpError);
|
|
55
|
+
controller.abort();
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
logger.debug(`Response from "${url.toString()}":`, response);
|
|
59
|
+
return response;
|
|
60
|
+
} catch (error) {
|
|
61
|
+
if (error instanceof HttpError && error.status === RETRY_RESPONSE_STATUS) throw error;
|
|
62
|
+
logger.error(`Request to "${url.toString()}" failed:`, error);
|
|
63
|
+
controller.abort();
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function createRetryFetchMethod({ apiName = 'Optimization', fetchMethod = fetch, intervalTimeout = DEFAULT_INTERVAL_TIMEOUT, onFailedAttempt, retries = DEFAULT_RETRY_COUNT } = {}) {
|
|
68
|
+
return async (url, init)=>{
|
|
69
|
+
const controller = new AbortController();
|
|
70
|
+
let retryResponse;
|
|
71
|
+
try {
|
|
72
|
+
retryResponse = await external_p_retry_default()(createRetryFetchCallback({
|
|
73
|
+
apiName,
|
|
74
|
+
controller,
|
|
75
|
+
fetchMethod,
|
|
76
|
+
init,
|
|
77
|
+
url
|
|
78
|
+
}), {
|
|
79
|
+
minTimeout: intervalTimeout,
|
|
80
|
+
onFailedAttempt: (options)=>onFailedAttempt?.({
|
|
81
|
+
...options,
|
|
82
|
+
apiName
|
|
83
|
+
}),
|
|
84
|
+
retries,
|
|
85
|
+
signal: controller.signal
|
|
86
|
+
});
|
|
87
|
+
} catch (error) {
|
|
88
|
+
if (!(error instanceof Error) || 'AbortError' !== error.name) throw error;
|
|
89
|
+
}
|
|
90
|
+
if (!retryResponse) throw new Error(`${apiName} API request to "${url.toString()}" may not be retried.`);
|
|
91
|
+
return retryResponse;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
const createTimeoutFetchMethod_logger = (0, dist.zP)('ApiClient:Timeout');
|
|
95
|
+
const DEFAULT_REQUEST_TIMEOUT = 3000;
|
|
96
|
+
function createTimeoutFetchMethod({ apiName = 'Optimization', fetchMethod = fetch, onRequestTimeout, requestTimeout = DEFAULT_REQUEST_TIMEOUT } = {}) {
|
|
97
|
+
return async (url, init)=>{
|
|
98
|
+
const controller = new AbortController();
|
|
99
|
+
const id = setTimeout(()=>{
|
|
100
|
+
if ('function' == typeof onRequestTimeout) onRequestTimeout({
|
|
101
|
+
apiName
|
|
102
|
+
});
|
|
103
|
+
else createTimeoutFetchMethod_logger.error(`Request to "${url.toString()}" timed out`, new Error('Request timeout'));
|
|
104
|
+
controller.abort();
|
|
105
|
+
}, requestTimeout);
|
|
106
|
+
const response = await fetchMethod(url, {
|
|
107
|
+
...init,
|
|
108
|
+
signal: controller.signal
|
|
109
|
+
});
|
|
110
|
+
clearTimeout(id);
|
|
111
|
+
return response;
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
const createProtectedFetchMethod_logger = (0, dist.zP)('ApiClient:Fetch');
|
|
115
|
+
function createProtectedFetchMethod(options) {
|
|
116
|
+
try {
|
|
117
|
+
const timeoutFetchMethod = createTimeoutFetchMethod(options);
|
|
118
|
+
const retryFetchMethod = createRetryFetchMethod({
|
|
119
|
+
...options,
|
|
120
|
+
fetchMethod: timeoutFetchMethod
|
|
121
|
+
});
|
|
122
|
+
return retryFetchMethod;
|
|
123
|
+
} catch (error) {
|
|
124
|
+
if (error instanceof Error) if ('AbortError' === error.name) createProtectedFetchMethod_logger.warn('Request aborted due to network issues. This request may not be retried.');
|
|
125
|
+
else createProtectedFetchMethod_logger.error('Request failed:', error);
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const Fetch = {
|
|
130
|
+
create: createProtectedFetchMethod
|
|
131
|
+
};
|
|
132
|
+
const fetch_Fetch = Fetch;
|
|
133
|
+
const src_fetch = fetch_Fetch;
|
|
134
|
+
const ApiClientBase_logger = (0, dist.zP)('ApiClient');
|
|
135
|
+
const DEFAULT_ENVIRONMENT = 'main';
|
|
136
|
+
class ApiClientBase {
|
|
137
|
+
name;
|
|
138
|
+
clientId;
|
|
139
|
+
environment;
|
|
140
|
+
fetch;
|
|
141
|
+
constructor(name, { fetchOptions, clientId, environment }){
|
|
142
|
+
this.clientId = clientId;
|
|
143
|
+
this.environment = environment ?? DEFAULT_ENVIRONMENT;
|
|
144
|
+
this.name = name;
|
|
145
|
+
this.fetch = src_fetch.create({
|
|
146
|
+
...fetchOptions ?? {},
|
|
147
|
+
apiName: name
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
logRequestError(error, { requestName }) {
|
|
151
|
+
if (error instanceof Error) if ('AbortError' === error.name) ApiClientBase_logger.warn(`[${this.name}] "${requestName}" request aborted due to network issues. This request may not be retried.`);
|
|
152
|
+
else ApiClientBase_logger.error(`[${this.name}] "${requestName}" request failed:`, error);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const src_ApiClientBase = ApiClientBase;
|
|
156
|
+
},
|
|
157
|
+
"./src/builders/index.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
158
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
159
|
+
c: ()=>DEFAULT_PAGE_PROPERTIES,
|
|
160
|
+
e: ()=>builders_EventBuilder
|
|
161
|
+
});
|
|
162
|
+
var optimization_api_schemas_ = __webpack_require__("@contentful/optimization-api-schemas");
|
|
163
|
+
const external_es_toolkit_namespaceObject = require("es-toolkit");
|
|
164
|
+
const mini_namespaceObject = require("zod/mini");
|
|
165
|
+
const UniversalEventBuilderArgs = mini_namespaceObject.object({
|
|
166
|
+
campaign: mini_namespaceObject.optional(optimization_api_schemas_.Campaign),
|
|
167
|
+
locale: mini_namespaceObject.optional(mini_namespaceObject.string()),
|
|
168
|
+
location: mini_namespaceObject.optional(optimization_api_schemas_.GeoLocation),
|
|
169
|
+
page: mini_namespaceObject.optional(optimization_api_schemas_.Page),
|
|
170
|
+
screen: mini_namespaceObject.optional(optimization_api_schemas_.Screen),
|
|
171
|
+
userAgent: mini_namespaceObject.optional(mini_namespaceObject.string())
|
|
172
|
+
});
|
|
173
|
+
const ComponentViewBuilderArgs = mini_namespaceObject.extend(UniversalEventBuilderArgs, {
|
|
174
|
+
componentId: mini_namespaceObject.string(),
|
|
175
|
+
experienceId: mini_namespaceObject.optional(mini_namespaceObject.string()),
|
|
176
|
+
variantIndex: mini_namespaceObject.optional(mini_namespaceObject.number()),
|
|
177
|
+
sticky: mini_namespaceObject.optional(mini_namespaceObject.boolean())
|
|
178
|
+
});
|
|
179
|
+
const IdentifyBuilderArgs = mini_namespaceObject.extend(UniversalEventBuilderArgs, {
|
|
180
|
+
traits: mini_namespaceObject.optional(optimization_api_schemas_.Traits),
|
|
181
|
+
userId: mini_namespaceObject.string()
|
|
182
|
+
});
|
|
183
|
+
const PageViewBuilderArgs = mini_namespaceObject.extend(UniversalEventBuilderArgs, {
|
|
184
|
+
properties: mini_namespaceObject.optional(mini_namespaceObject.partial(optimization_api_schemas_.Page))
|
|
185
|
+
});
|
|
186
|
+
const ScreenViewBuilderArgs = mini_namespaceObject.extend(UniversalEventBuilderArgs, {
|
|
187
|
+
name: mini_namespaceObject.string(),
|
|
188
|
+
properties: optimization_api_schemas_.Properties
|
|
189
|
+
});
|
|
190
|
+
const TrackBuilderArgs = mini_namespaceObject.extend(UniversalEventBuilderArgs, {
|
|
191
|
+
event: mini_namespaceObject.string(),
|
|
192
|
+
properties: mini_namespaceObject.optional(mini_namespaceObject.prefault(optimization_api_schemas_.Properties, {}))
|
|
193
|
+
});
|
|
194
|
+
const DEFAULT_PAGE_PROPERTIES = {
|
|
195
|
+
path: '',
|
|
196
|
+
query: {},
|
|
197
|
+
referrer: '',
|
|
198
|
+
search: '',
|
|
199
|
+
title: '',
|
|
200
|
+
url: ''
|
|
201
|
+
};
|
|
202
|
+
class EventBuilder {
|
|
203
|
+
app;
|
|
204
|
+
channel;
|
|
205
|
+
library;
|
|
206
|
+
getLocale;
|
|
207
|
+
getPageProperties;
|
|
208
|
+
getUserAgent;
|
|
209
|
+
constructor(config){
|
|
210
|
+
const { app, channel, library, getLocale, getPageProperties, getUserAgent } = config;
|
|
211
|
+
this.app = app;
|
|
212
|
+
this.channel = channel;
|
|
213
|
+
this.library = library;
|
|
214
|
+
this.getLocale = getLocale ?? (()=>'en-US');
|
|
215
|
+
this.getPageProperties = getPageProperties ?? (()=>DEFAULT_PAGE_PROPERTIES);
|
|
216
|
+
this.getUserAgent = getUserAgent ?? (()=>void 0);
|
|
217
|
+
}
|
|
218
|
+
buildUniversalEventProperties({ campaign = {}, locale, location, page, screen, userAgent }) {
|
|
219
|
+
const timestamp = new Date().toISOString();
|
|
220
|
+
return {
|
|
221
|
+
channel: this.channel,
|
|
222
|
+
context: {
|
|
223
|
+
app: this.app,
|
|
224
|
+
campaign,
|
|
225
|
+
gdpr: {
|
|
226
|
+
isConsentGiven: true
|
|
227
|
+
},
|
|
228
|
+
library: this.library,
|
|
229
|
+
locale: locale ?? this.getLocale() ?? 'en-US',
|
|
230
|
+
location,
|
|
231
|
+
page: page ?? this.getPageProperties(),
|
|
232
|
+
screen,
|
|
233
|
+
userAgent: userAgent ?? this.getUserAgent()
|
|
234
|
+
},
|
|
235
|
+
messageId: crypto.randomUUID(),
|
|
236
|
+
originalTimestamp: timestamp,
|
|
237
|
+
sentAt: timestamp,
|
|
238
|
+
timestamp
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
buildComponentView(args) {
|
|
242
|
+
const { componentId, experienceId, variantIndex, ...universal } = ComponentViewBuilderArgs.parse(args);
|
|
243
|
+
return {
|
|
244
|
+
...this.buildUniversalEventProperties(universal),
|
|
245
|
+
type: 'component',
|
|
246
|
+
componentType: 'Entry',
|
|
247
|
+
componentId,
|
|
248
|
+
experienceId,
|
|
249
|
+
variantIndex: variantIndex ?? 0
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
buildFlagView(args) {
|
|
253
|
+
return {
|
|
254
|
+
...this.buildComponentView(args),
|
|
255
|
+
componentType: 'Variable'
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
buildIdentify(args) {
|
|
259
|
+
const { traits = {}, userId, ...universal } = IdentifyBuilderArgs.parse(args);
|
|
260
|
+
return {
|
|
261
|
+
...this.buildUniversalEventProperties(universal),
|
|
262
|
+
type: 'identify',
|
|
263
|
+
traits,
|
|
264
|
+
userId
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
buildPageView(args = {}) {
|
|
268
|
+
const { properties = {}, ...universal } = PageViewBuilderArgs.parse(args);
|
|
269
|
+
const pageProperties = this.getPageProperties();
|
|
270
|
+
const merged = (0, external_es_toolkit_namespaceObject.merge)({
|
|
271
|
+
...pageProperties,
|
|
272
|
+
title: pageProperties.title ?? DEFAULT_PAGE_PROPERTIES.title
|
|
273
|
+
}, properties);
|
|
274
|
+
const { context: { screen: _, ...universalContext }, ...universalProperties } = this.buildUniversalEventProperties(universal);
|
|
275
|
+
const context = optimization_api_schemas_.PageEventContext.parse(universalContext);
|
|
276
|
+
return {
|
|
277
|
+
...universalProperties,
|
|
278
|
+
context,
|
|
279
|
+
type: 'page',
|
|
280
|
+
properties: merged
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
buildScreenView(args) {
|
|
284
|
+
const { name, properties, ...universal } = ScreenViewBuilderArgs.parse(args);
|
|
285
|
+
const { context: { page: _, ...universalContext }, ...universalProperties } = this.buildUniversalEventProperties(universal);
|
|
286
|
+
const context = optimization_api_schemas_.ScreenEventContext.parse(universalContext);
|
|
287
|
+
return {
|
|
288
|
+
...universalProperties,
|
|
289
|
+
context,
|
|
290
|
+
type: 'screen',
|
|
291
|
+
name,
|
|
292
|
+
properties
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
buildTrack(args) {
|
|
296
|
+
const { event, properties = {}, ...universal } = TrackBuilderArgs.parse(args);
|
|
297
|
+
return {
|
|
298
|
+
...this.buildUniversalEventProperties(universal),
|
|
299
|
+
type: 'track',
|
|
300
|
+
event,
|
|
301
|
+
properties
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
const builders_EventBuilder = EventBuilder;
|
|
306
|
+
},
|
|
307
|
+
"./src/experience/index.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
308
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
309
|
+
n: ()=>EXPERIENCE_BASE_URL,
|
|
310
|
+
A: ()=>experience
|
|
311
|
+
});
|
|
312
|
+
var optimization_api_schemas_ = __webpack_require__("@contentful/optimization-api-schemas");
|
|
313
|
+
var dist = __webpack_require__("../../lib/logger/dist/index.mjs");
|
|
314
|
+
var ApiClientBase = __webpack_require__("./src/ApiClientBase.ts");
|
|
315
|
+
const logger = (0, dist.zP)('ApiClient:Experience');
|
|
316
|
+
const EXPERIENCE_BASE_URL = 'https://experience.ninetailed.co/';
|
|
317
|
+
class ExperienceApiClient extends ApiClientBase.A {
|
|
318
|
+
baseUrl;
|
|
319
|
+
enabledFeatures;
|
|
320
|
+
ip;
|
|
321
|
+
locale;
|
|
322
|
+
plainText;
|
|
323
|
+
preflight;
|
|
324
|
+
constructor(config){
|
|
325
|
+
super('Experience', config);
|
|
326
|
+
const { baseUrl, enabledFeatures, ip, locale, plainText, preflight } = config;
|
|
327
|
+
this.baseUrl = baseUrl || EXPERIENCE_BASE_URL;
|
|
328
|
+
this.enabledFeatures = enabledFeatures;
|
|
329
|
+
this.ip = ip;
|
|
330
|
+
this.locale = locale;
|
|
331
|
+
this.plainText = plainText;
|
|
332
|
+
this.preflight = preflight;
|
|
333
|
+
}
|
|
334
|
+
async getProfile(id, options = {}) {
|
|
335
|
+
if (!id) throw new Error('Valid profile ID required.');
|
|
336
|
+
const requestName = 'Get Profile';
|
|
337
|
+
logger.info(`Sending "${requestName}" request`);
|
|
338
|
+
try {
|
|
339
|
+
const response = await this.fetch(this.constructUrl(`v2/organizations/${this.clientId}/environments/${this.environment}/profiles/${id}`, options), {
|
|
340
|
+
method: 'GET'
|
|
341
|
+
});
|
|
342
|
+
const { data: { changes, experiences, profile } } = optimization_api_schemas_.ExperienceResponse.parse(await response.json());
|
|
343
|
+
const data = {
|
|
344
|
+
changes,
|
|
345
|
+
personalizations: experiences,
|
|
346
|
+
profile
|
|
347
|
+
};
|
|
348
|
+
logger.debug(`"${requestName}" request successfully completed`);
|
|
349
|
+
return data;
|
|
350
|
+
} catch (error) {
|
|
351
|
+
this.logRequestError(error, {
|
|
352
|
+
requestName
|
|
353
|
+
});
|
|
354
|
+
throw error;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
async makeProfileMutationRequest({ url, body, options }) {
|
|
358
|
+
return await this.fetch(this.constructUrl(url, options), {
|
|
359
|
+
method: 'POST',
|
|
360
|
+
headers: this.constructHeaders(options),
|
|
361
|
+
body: JSON.stringify(body),
|
|
362
|
+
keepalive: true
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
async createProfile({ events }, options = {}) {
|
|
366
|
+
const requestName = 'Create Profile';
|
|
367
|
+
logger.info(`Sending "${requestName}" request`);
|
|
368
|
+
const body = {
|
|
369
|
+
events: optimization_api_schemas_.ExperienceEventArray.parse(events),
|
|
370
|
+
options: this.constructBodyOptions(options)
|
|
371
|
+
};
|
|
372
|
+
logger.debug(`"${requestName}" request body:`, body);
|
|
373
|
+
try {
|
|
374
|
+
const response = await this.makeProfileMutationRequest({
|
|
375
|
+
url: `v2/organizations/${this.clientId}/environments/${this.environment}/profiles`,
|
|
376
|
+
body,
|
|
377
|
+
options
|
|
378
|
+
});
|
|
379
|
+
const { data: { changes, experiences, profile } } = optimization_api_schemas_.ExperienceResponse.parse(await response.json());
|
|
380
|
+
const data = {
|
|
381
|
+
changes,
|
|
382
|
+
personalizations: experiences,
|
|
383
|
+
profile
|
|
384
|
+
};
|
|
385
|
+
logger.debug(`"${requestName}" request successfully completed`);
|
|
386
|
+
return data;
|
|
387
|
+
} catch (error) {
|
|
388
|
+
this.logRequestError(error, {
|
|
389
|
+
requestName
|
|
390
|
+
});
|
|
391
|
+
throw error;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
async updateProfile({ profileId, events }, options = {}) {
|
|
395
|
+
if (!profileId) throw new Error('Valid profile ID required.');
|
|
396
|
+
const requestName = 'Update Profile';
|
|
397
|
+
logger.info(`Sending "${requestName}" request`);
|
|
398
|
+
const body = {
|
|
399
|
+
events: optimization_api_schemas_.ExperienceEventArray.parse(events),
|
|
400
|
+
options: this.constructBodyOptions(options)
|
|
401
|
+
};
|
|
402
|
+
logger.debug(`"${requestName}" request body:`, body);
|
|
403
|
+
try {
|
|
404
|
+
const response = await this.makeProfileMutationRequest({
|
|
405
|
+
url: `v2/organizations/${this.clientId}/environments/${this.environment}/profiles/${profileId}`,
|
|
406
|
+
body,
|
|
407
|
+
options
|
|
408
|
+
});
|
|
409
|
+
const { data: { changes, experiences, profile } } = optimization_api_schemas_.ExperienceResponse.parse(await response.json());
|
|
410
|
+
const data = {
|
|
411
|
+
changes,
|
|
412
|
+
personalizations: experiences,
|
|
413
|
+
profile
|
|
414
|
+
};
|
|
415
|
+
logger.debug(`"${requestName}" request successfully completed`);
|
|
416
|
+
return data;
|
|
417
|
+
} catch (error) {
|
|
418
|
+
this.logRequestError(error, {
|
|
419
|
+
requestName
|
|
420
|
+
});
|
|
421
|
+
throw error;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
async upsertProfile({ profileId, events }, options) {
|
|
425
|
+
if (!profileId) return await this.createProfile({
|
|
426
|
+
events
|
|
427
|
+
}, options);
|
|
428
|
+
return await this.updateProfile({
|
|
429
|
+
profileId,
|
|
430
|
+
events
|
|
431
|
+
}, options);
|
|
432
|
+
}
|
|
433
|
+
async upsertManyProfiles({ events }, options = {}) {
|
|
434
|
+
const requestName = 'Upsert Many Profiles';
|
|
435
|
+
logger.info(`Sending "${requestName}" request`);
|
|
436
|
+
const body = {
|
|
437
|
+
events: optimization_api_schemas_.ExperienceEventArray.parse(events),
|
|
438
|
+
options: this.constructBodyOptions(options)
|
|
439
|
+
};
|
|
440
|
+
logger.debug(`"${requestName}" request body:`, body);
|
|
441
|
+
try {
|
|
442
|
+
const response = await this.makeProfileMutationRequest({
|
|
443
|
+
url: `v2/organizations/${this.clientId}/environments/${this.environment}/events`,
|
|
444
|
+
body,
|
|
445
|
+
options: {
|
|
446
|
+
plainText: false,
|
|
447
|
+
...options
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
const { data: { profiles } } = optimization_api_schemas_.BatchExperienceResponse.parse(await response.json());
|
|
451
|
+
logger.debug(`"${requestName}" request successfully completed`);
|
|
452
|
+
return profiles;
|
|
453
|
+
} catch (error) {
|
|
454
|
+
this.logRequestError(error, {
|
|
455
|
+
requestName
|
|
456
|
+
});
|
|
457
|
+
throw error;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
constructUrl(path, options) {
|
|
461
|
+
const url = new URL(path, this.baseUrl);
|
|
462
|
+
const locale = options.locale ?? this.locale;
|
|
463
|
+
const preflight = options.preflight ?? this.preflight;
|
|
464
|
+
if (locale) url.searchParams.set('locale', locale);
|
|
465
|
+
if (preflight) url.searchParams.set('type', 'preflight');
|
|
466
|
+
return url.toString();
|
|
467
|
+
}
|
|
468
|
+
constructHeaders({ ip = this.ip, plainText = this.plainText }) {
|
|
469
|
+
const headers = new Map();
|
|
470
|
+
if (ip) headers.set('X-Force-IP', ip);
|
|
471
|
+
if (plainText ?? this.plainText ?? true) headers.set('Content-Type', 'text/plain');
|
|
472
|
+
else headers.set('Content-Type', 'application/json');
|
|
473
|
+
return Object.fromEntries(headers);
|
|
474
|
+
}
|
|
475
|
+
constructBodyOptions = ({ enabledFeatures = this.enabledFeatures })=>{
|
|
476
|
+
const bodyOptions = {};
|
|
477
|
+
if (enabledFeatures && Array.isArray(enabledFeatures) && enabledFeatures.length > 0) bodyOptions.features = enabledFeatures;
|
|
478
|
+
else bodyOptions.features = [
|
|
479
|
+
'ip-enrichment',
|
|
480
|
+
'location'
|
|
481
|
+
];
|
|
482
|
+
return bodyOptions;
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
const experience = ExperienceApiClient;
|
|
486
|
+
},
|
|
487
|
+
"./src/insights/index.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
488
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
489
|
+
Q: ()=>INSIGHTS_BASE_URL,
|
|
490
|
+
A: ()=>insights
|
|
491
|
+
});
|
|
492
|
+
var optimization_api_schemas_ = __webpack_require__("@contentful/optimization-api-schemas");
|
|
493
|
+
var dist = __webpack_require__("../../lib/logger/dist/index.mjs");
|
|
494
|
+
var ApiClientBase = __webpack_require__("./src/ApiClientBase.ts");
|
|
495
|
+
const logger = (0, dist.zP)('ApiClient:Insights');
|
|
496
|
+
const INSIGHTS_BASE_URL = 'https://ingest.insights.ninetailed.co/';
|
|
497
|
+
class InsightsApiClient extends ApiClientBase.A {
|
|
498
|
+
baseUrl;
|
|
499
|
+
beaconHandler;
|
|
500
|
+
constructor(config){
|
|
501
|
+
super('Insights', config);
|
|
502
|
+
const { baseUrl, beaconHandler } = config;
|
|
503
|
+
this.baseUrl = baseUrl ?? INSIGHTS_BASE_URL;
|
|
504
|
+
this.beaconHandler = beaconHandler;
|
|
505
|
+
}
|
|
506
|
+
async sendBatchEvents(batches, options = {}) {
|
|
507
|
+
const { beaconHandler = this.beaconHandler } = options;
|
|
508
|
+
const url = new URL(`v1/organizations/${this.clientId}/environments/${this.environment}/events`, this.baseUrl);
|
|
509
|
+
const body = optimization_api_schemas_.BatchInsightsEventArray.parse(batches);
|
|
510
|
+
if ('function' == typeof beaconHandler) {
|
|
511
|
+
logger.debug('Queueing events via beaconHandler');
|
|
512
|
+
const beaconSuccessfullyQueued = beaconHandler(url, body);
|
|
513
|
+
if (beaconSuccessfullyQueued) return true;
|
|
514
|
+
logger.warn('beaconHandler failed to queue events; events will be emitted immediately via fetch');
|
|
515
|
+
}
|
|
516
|
+
const requestName = 'Event Batches';
|
|
517
|
+
logger.info(`Sending "${requestName}" request`);
|
|
518
|
+
logger.debug(`"${requestName}" request body:`, body);
|
|
519
|
+
try {
|
|
520
|
+
await this.fetch(url, {
|
|
521
|
+
method: 'POST',
|
|
522
|
+
headers: {
|
|
523
|
+
'Content-Type': 'application/json'
|
|
524
|
+
},
|
|
525
|
+
body: JSON.stringify(body),
|
|
526
|
+
keepalive: true
|
|
527
|
+
});
|
|
528
|
+
logger.debug(`"${requestName}" request successfully completed`);
|
|
529
|
+
return true;
|
|
530
|
+
} catch (error) {
|
|
531
|
+
this.logRequestError(error, {
|
|
532
|
+
requestName
|
|
533
|
+
});
|
|
534
|
+
return false;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
const insights = InsightsApiClient;
|
|
539
|
+
},
|
|
540
|
+
"@contentful/optimization-api-schemas" (module) {
|
|
541
|
+
module.exports = require("@contentful/optimization-api-schemas");
|
|
542
|
+
},
|
|
543
|
+
"../../lib/logger/dist/index.mjs" (__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
544
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
545
|
+
zP: ()=>createScopedLogger
|
|
546
|
+
});
|
|
547
|
+
const external_diary_namespaceObject = require("diary");
|
|
548
|
+
require("diary/utils");
|
|
549
|
+
class Logger {
|
|
550
|
+
name = '@contentful/optimization';
|
|
551
|
+
PREFIX_PARTS = [
|
|
552
|
+
'Ctfl',
|
|
553
|
+
'O10n'
|
|
554
|
+
];
|
|
555
|
+
DELIMITER = ':';
|
|
556
|
+
diary;
|
|
557
|
+
sinks = [];
|
|
558
|
+
constructor(){
|
|
559
|
+
this.diary = (0, external_diary_namespaceObject.diary)(this.name, this.onLogEvent.bind(this));
|
|
560
|
+
(0, external_diary_namespaceObject.enable)(this.name);
|
|
561
|
+
}
|
|
562
|
+
assembleLocationPrefix(logLocation) {
|
|
563
|
+
return `[${[
|
|
564
|
+
...this.PREFIX_PARTS,
|
|
565
|
+
logLocation
|
|
566
|
+
].join(this.DELIMITER)}]`;
|
|
567
|
+
}
|
|
568
|
+
addSink(sink) {
|
|
569
|
+
this.sinks = [
|
|
570
|
+
...this.sinks.filter((existingSink)=>existingSink.name !== sink.name),
|
|
571
|
+
sink
|
|
572
|
+
];
|
|
573
|
+
}
|
|
574
|
+
removeSink(name) {
|
|
575
|
+
this.sinks = this.sinks.filter((sink)=>sink.name !== name);
|
|
576
|
+
}
|
|
577
|
+
removeSinks() {
|
|
578
|
+
this.sinks = [];
|
|
579
|
+
}
|
|
580
|
+
debug(logLocation, message, ...args) {
|
|
581
|
+
this.diary.debug(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
|
|
582
|
+
}
|
|
583
|
+
info(logLocation, message, ...args) {
|
|
584
|
+
this.diary.info(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
|
|
585
|
+
}
|
|
586
|
+
log(logLocation, message, ...args) {
|
|
587
|
+
this.diary.log(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
|
|
588
|
+
}
|
|
589
|
+
warn(logLocation, message, ...args) {
|
|
590
|
+
this.diary.warn(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
|
|
591
|
+
}
|
|
592
|
+
error(logLocation, message, ...args) {
|
|
593
|
+
this.diary.error(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
|
|
594
|
+
}
|
|
595
|
+
fatal(logLocation, message, ...args) {
|
|
596
|
+
this.diary.fatal(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
|
|
597
|
+
}
|
|
598
|
+
onLogEvent(event) {
|
|
599
|
+
this.sinks.forEach((sink)=>{
|
|
600
|
+
sink.ingest(event);
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
const logger = new Logger();
|
|
605
|
+
function createScopedLogger(location) {
|
|
606
|
+
return {
|
|
607
|
+
debug: (message, ...args)=>{
|
|
608
|
+
logger.debug(location, message, ...args);
|
|
609
|
+
},
|
|
610
|
+
info: (message, ...args)=>{
|
|
611
|
+
logger.info(location, message, ...args);
|
|
612
|
+
},
|
|
613
|
+
log: (message, ...args)=>{
|
|
614
|
+
logger.log(location, message, ...args);
|
|
615
|
+
},
|
|
616
|
+
warn: (message, ...args)=>{
|
|
617
|
+
logger.warn(location, message, ...args);
|
|
618
|
+
},
|
|
619
|
+
error: (message, ...args)=>{
|
|
620
|
+
logger.error(location, message, ...args);
|
|
621
|
+
},
|
|
622
|
+
fatal: (message, ...args)=>{
|
|
623
|
+
logger.fatal(location, message, ...args);
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
};
|
|
629
|
+
var __webpack_module_cache__ = {};
|
|
630
|
+
function __webpack_require__(moduleId) {
|
|
631
|
+
var cachedModule = __webpack_module_cache__[moduleId];
|
|
632
|
+
if (void 0 !== cachedModule) return cachedModule.exports;
|
|
633
|
+
var module = __webpack_module_cache__[moduleId] = {
|
|
634
|
+
exports: {}
|
|
635
|
+
};
|
|
636
|
+
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
637
|
+
return module.exports;
|
|
638
|
+
}
|
|
639
|
+
(()=>{
|
|
640
|
+
__webpack_require__.n = (module)=>{
|
|
641
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
642
|
+
__webpack_require__.d(getter, {
|
|
643
|
+
a: getter
|
|
644
|
+
});
|
|
645
|
+
return getter;
|
|
646
|
+
};
|
|
647
|
+
})();
|
|
648
|
+
(()=>{
|
|
649
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
650
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
651
|
+
enumerable: true,
|
|
652
|
+
get: definition[key]
|
|
653
|
+
});
|
|
654
|
+
};
|
|
655
|
+
})();
|
|
656
|
+
(()=>{
|
|
657
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
658
|
+
})();
|
|
659
|
+
(()=>{
|
|
660
|
+
__webpack_require__.r = (exports1)=>{
|
|
661
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
662
|
+
value: 'Module'
|
|
663
|
+
});
|
|
664
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
665
|
+
value: true
|
|
666
|
+
});
|
|
667
|
+
};
|
|
668
|
+
})();
|
|
669
|
+
var __webpack_exports__ = {};
|
|
670
|
+
(()=>{
|
|
671
|
+
__webpack_require__.r(__webpack_exports__);
|
|
672
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
673
|
+
ApiClient: ()=>_ApiClient__rspack_import_0.A,
|
|
674
|
+
DEFAULT_PAGE_PROPERTIES: ()=>_builders__rspack_import_3.c,
|
|
675
|
+
EXPERIENCE_BASE_URL: ()=>_experience__rspack_import_4.n,
|
|
676
|
+
EventBuilder: ()=>_builders__rspack_import_3.e,
|
|
677
|
+
INSIGHTS_BASE_URL: ()=>_insights__rspack_import_5.Q
|
|
678
|
+
});
|
|
679
|
+
var _ApiClient__rspack_import_0 = __webpack_require__("./src/ApiClient.ts");
|
|
680
|
+
var _contentful_optimization_api_schemas__rspack_import_1 = __webpack_require__("@contentful/optimization-api-schemas");
|
|
681
|
+
var __rspack_reexport = {};
|
|
682
|
+
for(const __rspack_import_key in _contentful_optimization_api_schemas__rspack_import_1)if ([
|
|
683
|
+
"default",
|
|
684
|
+
"ApiClient"
|
|
685
|
+
].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>_contentful_optimization_api_schemas__rspack_import_1[__rspack_import_key];
|
|
686
|
+
__webpack_require__.d(__webpack_exports__, __rspack_reexport);
|
|
687
|
+
__webpack_require__("./src/ApiClientBase.ts");
|
|
688
|
+
var _builders__rspack_import_3 = __webpack_require__("./src/builders/index.ts");
|
|
689
|
+
var _experience__rspack_import_4 = __webpack_require__("./src/experience/index.ts");
|
|
690
|
+
var _insights__rspack_import_5 = __webpack_require__("./src/insights/index.ts");
|
|
691
|
+
})();
|
|
692
|
+
exports.ApiClient = __webpack_exports__.ApiClient;
|
|
693
|
+
exports.DEFAULT_PAGE_PROPERTIES = __webpack_exports__.DEFAULT_PAGE_PROPERTIES;
|
|
694
|
+
exports.EXPERIENCE_BASE_URL = __webpack_exports__.EXPERIENCE_BASE_URL;
|
|
695
|
+
exports.EventBuilder = __webpack_exports__.EventBuilder;
|
|
696
|
+
exports.INSIGHTS_BASE_URL = __webpack_exports__.INSIGHTS_BASE_URL;
|
|
697
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
698
|
+
"ApiClient",
|
|
699
|
+
"DEFAULT_PAGE_PROPERTIES",
|
|
700
|
+
"EXPERIENCE_BASE_URL",
|
|
701
|
+
"EventBuilder",
|
|
702
|
+
"INSIGHTS_BASE_URL"
|
|
703
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
704
|
+
Object.defineProperty(exports, '__esModule', {
|
|
705
|
+
value: true
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
//# sourceMappingURL=index.cjs.map
|