@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.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +282 -0
  3. package/dist/ApiClient.d.ts +74 -0
  4. package/dist/ApiClient.d.ts.map +1 -0
  5. package/dist/ApiClient.js +61 -0
  6. package/dist/ApiClient.js.map +1 -0
  7. package/dist/ApiClientBase.d.ts +113 -0
  8. package/dist/ApiClientBase.d.ts.map +1 -0
  9. package/dist/ApiClientBase.js +94 -0
  10. package/dist/ApiClientBase.js.map +1 -0
  11. package/dist/builders/EventBuilder.d.ts +589 -0
  12. package/dist/builders/EventBuilder.d.ts.map +1 -0
  13. package/dist/builders/EventBuilder.js +349 -0
  14. package/dist/builders/EventBuilder.js.map +1 -0
  15. package/dist/builders/index.d.ts +3 -0
  16. package/dist/builders/index.d.ts.map +1 -0
  17. package/dist/builders/index.js +3 -0
  18. package/dist/builders/index.js.map +1 -0
  19. package/dist/experience/ExperienceApiClient.d.ts +267 -0
  20. package/dist/experience/ExperienceApiClient.d.ts.map +1 -0
  21. package/dist/experience/ExperienceApiClient.js +324 -0
  22. package/dist/experience/ExperienceApiClient.js.map +1 -0
  23. package/dist/experience/index.d.ts +4 -0
  24. package/dist/experience/index.d.ts.map +1 -0
  25. package/dist/experience/index.js +4 -0
  26. package/dist/experience/index.js.map +1 -0
  27. package/dist/fetch/Fetch.d.ts +96 -0
  28. package/dist/fetch/Fetch.d.ts.map +1 -0
  29. package/dist/fetch/Fetch.js +27 -0
  30. package/dist/fetch/Fetch.js.map +1 -0
  31. package/dist/fetch/createProtectedFetchMethod.d.ts +40 -0
  32. package/dist/fetch/createProtectedFetchMethod.d.ts.map +1 -0
  33. package/dist/fetch/createProtectedFetchMethod.js +53 -0
  34. package/dist/fetch/createProtectedFetchMethod.js.map +1 -0
  35. package/dist/fetch/createRetryFetchMethod.d.ts +60 -0
  36. package/dist/fetch/createRetryFetchMethod.d.ts.map +1 -0
  37. package/dist/fetch/createRetryFetchMethod.js +138 -0
  38. package/dist/fetch/createRetryFetchMethod.js.map +1 -0
  39. package/dist/fetch/createTimeoutFetchMethod.d.ts +51 -0
  40. package/dist/fetch/createTimeoutFetchMethod.d.ts.map +1 -0
  41. package/dist/fetch/createTimeoutFetchMethod.js +51 -0
  42. package/dist/fetch/createTimeoutFetchMethod.js.map +1 -0
  43. package/dist/fetch/index.d.ts +7 -0
  44. package/dist/fetch/index.d.ts.map +1 -0
  45. package/dist/fetch/index.js +7 -0
  46. package/dist/fetch/index.js.map +1 -0
  47. package/dist/index.cjs +708 -0
  48. package/dist/index.cjs.map +1 -0
  49. package/dist/index.d.ts +8 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/index.js +8 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/index.mjs +583 -0
  54. package/dist/index.mjs.map +1 -0
  55. package/dist/insights/InsightsApiClient.d.ts +130 -0
  56. package/dist/insights/InsightsApiClient.d.ts.map +1 -0
  57. package/dist/insights/InsightsApiClient.js +142 -0
  58. package/dist/insights/InsightsApiClient.js.map +1 -0
  59. package/dist/insights/index.d.ts +4 -0
  60. package/dist/insights/index.d.ts.map +1 -0
  61. package/dist/insights/index.js +4 -0
  62. package/dist/insights/index.js.map +1 -0
  63. 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