@contentful/optimization-api-client 0.1.0-alpha8 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +110 -218
  2. package/THIRD_PARTY_NOTICES.txt +2038 -0
  3. package/dist/199.mjs +2 -0
  4. package/dist/649.mjs +131 -0
  5. package/dist/649.mjs.map +1 -0
  6. package/dist/api-schemas.cjs +60 -0
  7. package/dist/api-schemas.cjs.map +1 -0
  8. package/dist/api-schemas.d.cts +4 -0
  9. package/dist/api-schemas.d.mts +4 -0
  10. package/dist/api-schemas.d.ts +4 -0
  11. package/dist/api-schemas.mjs +2 -0
  12. package/dist/index.cjs +452 -580
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +520 -1042
  15. package/dist/index.d.mts +520 -1042
  16. package/dist/index.d.ts +868 -8
  17. package/dist/index.mjs +115 -298
  18. package/dist/index.mjs.map +1 -1
  19. package/dist/logger.cjs +207 -0
  20. package/dist/logger.cjs.map +1 -0
  21. package/dist/logger.d.cts +287 -0
  22. package/dist/logger.d.mts +287 -0
  23. package/dist/logger.d.ts +287 -0
  24. package/dist/logger.mjs +1 -0
  25. package/package.json +37 -7
  26. package/dist/ApiClient.d.ts +0 -74
  27. package/dist/ApiClient.d.ts.map +0 -1
  28. package/dist/ApiClient.js +0 -61
  29. package/dist/ApiClient.js.map +0 -1
  30. package/dist/ApiClientBase.d.ts +0 -113
  31. package/dist/ApiClientBase.d.ts.map +0 -1
  32. package/dist/ApiClientBase.js +0 -94
  33. package/dist/ApiClientBase.js.map +0 -1
  34. package/dist/builders/EventBuilder.d.ts +0 -589
  35. package/dist/builders/EventBuilder.d.ts.map +0 -1
  36. package/dist/builders/EventBuilder.js +0 -349
  37. package/dist/builders/EventBuilder.js.map +0 -1
  38. package/dist/builders/index.d.ts +0 -3
  39. package/dist/builders/index.d.ts.map +0 -1
  40. package/dist/builders/index.js +0 -3
  41. package/dist/builders/index.js.map +0 -1
  42. package/dist/experience/ExperienceApiClient.d.ts +0 -267
  43. package/dist/experience/ExperienceApiClient.d.ts.map +0 -1
  44. package/dist/experience/ExperienceApiClient.js +0 -324
  45. package/dist/experience/ExperienceApiClient.js.map +0 -1
  46. package/dist/experience/index.d.ts +0 -4
  47. package/dist/experience/index.d.ts.map +0 -1
  48. package/dist/experience/index.js +0 -4
  49. package/dist/experience/index.js.map +0 -1
  50. package/dist/fetch/Fetch.d.ts +0 -96
  51. package/dist/fetch/Fetch.d.ts.map +0 -1
  52. package/dist/fetch/Fetch.js +0 -27
  53. package/dist/fetch/Fetch.js.map +0 -1
  54. package/dist/fetch/createProtectedFetchMethod.d.ts +0 -40
  55. package/dist/fetch/createProtectedFetchMethod.d.ts.map +0 -1
  56. package/dist/fetch/createProtectedFetchMethod.js +0 -53
  57. package/dist/fetch/createProtectedFetchMethod.js.map +0 -1
  58. package/dist/fetch/createRetryFetchMethod.d.ts +0 -60
  59. package/dist/fetch/createRetryFetchMethod.d.ts.map +0 -1
  60. package/dist/fetch/createRetryFetchMethod.js +0 -138
  61. package/dist/fetch/createRetryFetchMethod.js.map +0 -1
  62. package/dist/fetch/createTimeoutFetchMethod.d.ts +0 -51
  63. package/dist/fetch/createTimeoutFetchMethod.d.ts.map +0 -1
  64. package/dist/fetch/createTimeoutFetchMethod.js +0 -51
  65. package/dist/fetch/createTimeoutFetchMethod.js.map +0 -1
  66. package/dist/fetch/index.d.ts +0 -7
  67. package/dist/fetch/index.d.ts.map +0 -1
  68. package/dist/fetch/index.js +0 -7
  69. package/dist/fetch/index.js.map +0 -1
  70. package/dist/index.d.ts.map +0 -1
  71. package/dist/index.js +0 -8
  72. package/dist/index.js.map +0 -1
  73. package/dist/insights/InsightsApiClient.d.ts +0 -130
  74. package/dist/insights/InsightsApiClient.d.ts.map +0 -1
  75. package/dist/insights/InsightsApiClient.js +0 -143
  76. package/dist/insights/InsightsApiClient.js.map +0 -1
  77. package/dist/insights/index.d.ts +0 -4
  78. package/dist/insights/index.d.ts.map +0 -1
  79. package/dist/insights/index.js +0 -4
  80. package/dist/insights/index.js.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,88 +1,16 @@
1
- import * as __rspack_external__contentful_optimization_api_schemas_66dcf407 from "@contentful/optimization-api-schemas";
2
- import { diary, enable } from "diary";
3
- import "diary/utils";
4
- import p_retry from "p-retry";
5
- import { merge } from "es-toolkit";
6
- import { boolean as mini_boolean, extend, number, object, optional, partial, prefault, string } from "zod/mini";
7
- class Logger {
8
- name = '@contentful/optimization';
9
- PREFIX_PARTS = [
10
- 'Ctfl',
11
- 'O10n'
12
- ];
13
- DELIMITER = ':';
14
- diary;
15
- sinks = [];
16
- constructor(){
17
- this.diary = diary(this.name, this.onLogEvent.bind(this));
18
- enable(this.name);
19
- }
20
- assembleLocationPrefix(logLocation) {
21
- return `[${[
22
- ...this.PREFIX_PARTS,
23
- logLocation
24
- ].join(this.DELIMITER)}]`;
25
- }
26
- addSink(sink) {
27
- this.sinks = [
28
- ...this.sinks.filter((existingSink)=>existingSink.name !== sink.name),
29
- sink
30
- ];
31
- }
32
- removeSink(name) {
33
- this.sinks = this.sinks.filter((sink)=>sink.name !== name);
34
- }
35
- removeSinks() {
36
- this.sinks = [];
37
- }
38
- debug(logLocation, message, ...args) {
39
- this.diary.debug(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
40
- }
41
- info(logLocation, message, ...args) {
42
- this.diary.info(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
43
- }
44
- log(logLocation, message, ...args) {
45
- this.diary.log(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
46
- }
47
- warn(logLocation, message, ...args) {
48
- this.diary.warn(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
49
- }
50
- error(logLocation, message, ...args) {
51
- this.diary.error(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
52
- }
53
- fatal(logLocation, message, ...args) {
54
- this.diary.fatal(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
55
- }
56
- onLogEvent(event) {
57
- this.sinks.forEach((sink)=>{
58
- sink.ingest(event);
59
- });
60
- }
61
- }
62
- const logger = new Logger();
63
- function createScopedLogger(location) {
64
- return {
65
- debug: (message, ...args)=>{
66
- logger.debug(location, message, ...args);
67
- },
68
- info: (message, ...args)=>{
69
- logger.info(location, message, ...args);
70
- },
71
- log: (message, ...args)=>{
72
- logger.log(location, message, ...args);
73
- },
74
- warn: (message, ...args)=>{
75
- logger.warn(location, message, ...args);
76
- },
77
- error: (message, ...args)=>{
78
- logger.error(location, message, ...args);
79
- },
80
- fatal: (message, ...args)=>{
81
- logger.fatal(location, message, ...args);
82
- }
83
- };
1
+ import { createScopedLogger } from "./649.mjs";
2
+ import { __rspack_external__contentful_optimization_api_schemas_66dcf407 } from "./199.mjs";
3
+ const fetchInputToString = (input)=>{
4
+ if ('string' == typeof input) return input;
5
+ return input.url;
6
+ };
7
+ const MISSING_FETCH_METHOD_MESSAGE = 'No fetch implementation available. Provide a fetchMethod.';
8
+ function resolveFetchMethod(fetchMethod) {
9
+ if (fetchMethod) return fetchMethod;
10
+ if ('function' == typeof globalThis.fetch) return globalThis.fetch.bind(globalThis);
11
+ throw new Error(MISSING_FETCH_METHOD_MESSAGE);
84
12
  }
85
- const createRetryFetchMethod_logger = createScopedLogger('ApiClient:Retry');
13
+ const logger = createScopedLogger('ApiClient:Retry');
86
14
  const DEFAULT_INTERVAL_TIMEOUT = 0;
87
15
  const DEFAULT_RETRY_COUNT = 1;
88
16
  const RETRY_RESPONSE_STATUS = 503;
@@ -95,69 +23,89 @@ class HttpError extends Error {
95
23
  this.status = status;
96
24
  }
97
25
  }
98
- function createRetryFetchCallback({ apiName = 'Optimization', controller, fetchMethod = fetch, init, url }) {
26
+ function createRetryFetchCallback({ apiName = 'Optimization', controller, fetchMethod, init, url }) {
99
27
  return async ()=>{
28
+ const urlLabel = fetchInputToString(url);
100
29
  try {
101
30
  const response = await fetchMethod(url, init);
102
- 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);
31
+ if (response.status === RETRY_RESPONSE_STATUS) throw new HttpError(`${apiName} API request to "${urlLabel}" failed with status: "[${response.status}] ${response.statusText}".`, RETRY_RESPONSE_STATUS);
103
32
  if (!response.ok) {
104
- const httpError = new Error(`Request to "${url.toString()}" failed with status: [${response.status}] ${response.statusText} - traceparent: ${response.headers.get('traceparent')}`);
105
- createRetryFetchMethod_logger.error('Request failed with non-OK status:', httpError);
33
+ const httpError = new Error(`Request to "${urlLabel}" failed with status: [${response.status}] ${response.statusText} - traceparent: ${response.headers.get('traceparent')}`);
34
+ logger.error('Request failed with non-OK status:', httpError);
106
35
  controller.abort();
107
36
  return;
108
37
  }
109
- createRetryFetchMethod_logger.debug(`Response from "${url.toString()}":`, response);
38
+ logger.debug(`Response from "${urlLabel}":`, response);
110
39
  return response;
111
40
  } catch (error) {
112
41
  if (error instanceof HttpError && error.status === RETRY_RESPONSE_STATUS) throw error;
113
- createRetryFetchMethod_logger.error(`Request to "${url.toString()}" failed:`, error);
42
+ logger.error(`Request to "${urlLabel}" failed:`, error);
114
43
  controller.abort();
115
44
  }
116
45
  };
117
46
  }
118
- function createRetryFetchMethod({ apiName = 'Optimization', fetchMethod = fetch, intervalTimeout = DEFAULT_INTERVAL_TIMEOUT, onFailedAttempt, retries = DEFAULT_RETRY_COUNT } = {}) {
47
+ async function delayRetry(intervalTimeout) {
48
+ if (intervalTimeout <= 0) return;
49
+ const { promise, resolve } = Promise.withResolvers();
50
+ setTimeout(()=>{
51
+ resolve(void 0);
52
+ }, intervalTimeout);
53
+ await promise;
54
+ }
55
+ function createRetryFetchMethod({ apiName = 'Optimization', fetchMethod, intervalTimeout = DEFAULT_INTERVAL_TIMEOUT, onFailedAttempt, retries = DEFAULT_RETRY_COUNT } = {}) {
56
+ const resolvedFetchMethod = resolveFetchMethod(fetchMethod);
119
57
  return async (url, init)=>{
120
58
  const controller = new AbortController();
121
- let retryResponse;
122
- try {
123
- retryResponse = await p_retry(createRetryFetchCallback({
59
+ const maxAttempts = retries + 1;
60
+ const attemptFetch = createRetryFetchCallback({
61
+ apiName,
62
+ controller,
63
+ fetchMethod: resolvedFetchMethod,
64
+ init,
65
+ url
66
+ });
67
+ for(let attemptNumber = 1; attemptNumber <= maxAttempts; attemptNumber++)try {
68
+ const response = await attemptFetch();
69
+ if (response) return response;
70
+ break;
71
+ } catch (error) {
72
+ if (!(error instanceof HttpError) || error.status !== RETRY_RESPONSE_STATUS) throw error;
73
+ const retriesLeft = maxAttempts - attemptNumber;
74
+ onFailedAttempt?.({
124
75
  apiName,
125
- controller,
126
- fetchMethod,
127
- init,
128
- url
129
- }), {
130
- minTimeout: intervalTimeout,
131
- onFailedAttempt: (options)=>onFailedAttempt?.({
132
- ...options,
133
- apiName
134
- }),
135
- retries,
136
- signal: controller.signal
76
+ error,
77
+ attemptNumber,
78
+ retriesLeft
137
79
  });
138
- } catch (error) {
139
- if (!(error instanceof Error) || 'AbortError' !== error.name) throw error;
80
+ if (0 === retriesLeft) throw error;
81
+ await delayRetry(intervalTimeout);
140
82
  }
141
- if (!retryResponse) throw new Error(`${apiName} API request to "${url.toString()}" may not be retried.`);
142
- return retryResponse;
83
+ throw new Error(`${apiName} API request to "${fetchInputToString(url)}" may not be retried.`);
143
84
  };
144
85
  }
145
86
  const createTimeoutFetchMethod_logger = createScopedLogger('ApiClient:Timeout');
146
87
  const DEFAULT_REQUEST_TIMEOUT = 3000;
147
- function createTimeoutFetchMethod({ apiName = 'Optimization', fetchMethod = fetch, onRequestTimeout, requestTimeout = DEFAULT_REQUEST_TIMEOUT } = {}) {
88
+ function isFetchAbortSignal(signal) {
89
+ return 'object' == typeof signal && null !== signal;
90
+ }
91
+ function createTimeoutFetchMethod({ apiName = 'Optimization', fetchMethod, onRequestTimeout, requestTimeout = DEFAULT_REQUEST_TIMEOUT } = {}) {
92
+ const resolvedFetchMethod = resolveFetchMethod(fetchMethod);
148
93
  return async (url, init)=>{
149
94
  const controller = new AbortController();
150
95
  const id = setTimeout(()=>{
151
96
  if ('function' == typeof onRequestTimeout) onRequestTimeout({
152
97
  apiName
153
98
  });
154
- else createTimeoutFetchMethod_logger.error(`Request to "${url.toString()}" timed out`, new Error('Request timeout'));
99
+ else createTimeoutFetchMethod_logger.error(`Request to "${fetchInputToString(url)}" timed out`, new Error('Request timeout'));
155
100
  controller.abort();
156
101
  }, requestTimeout);
157
- const response = await fetchMethod(url, {
102
+ const { signal } = controller;
103
+ if (!isFetchAbortSignal(signal)) throw new Error('AbortController signal is not compatible with fetch.');
104
+ const requestInit = {
158
105
  ...init,
159
- signal: controller.signal
160
- });
106
+ signal
107
+ };
108
+ const response = await resolvedFetchMethod(url, requestInit);
161
109
  clearTimeout(id);
162
110
  return response;
163
111
  };
@@ -181,7 +129,7 @@ const Fetch = {
181
129
  create: createProtectedFetchMethod
182
130
  };
183
131
  const fetch_Fetch = Fetch;
184
- const src_fetch = fetch_Fetch;
132
+ const fetch = fetch_Fetch;
185
133
  const ApiClientBase_logger = createScopedLogger('ApiClient');
186
134
  const DEFAULT_ENVIRONMENT = 'main';
187
135
  class ApiClientBase {
@@ -193,7 +141,7 @@ class ApiClientBase {
193
141
  this.clientId = clientId;
194
142
  this.environment = environment ?? DEFAULT_ENVIRONMENT;
195
143
  this.name = name;
196
- this.fetch = src_fetch.create({
144
+ this.fetch = fetch.create({
197
145
  ...fetchOptions ?? {},
198
146
  apiName: name
199
147
  });
@@ -223,6 +171,9 @@ class ExperienceApiClient extends src_ApiClientBase {
223
171
  this.plainText = plainText;
224
172
  this.preflight = preflight;
225
173
  }
174
+ setLocale(locale) {
175
+ this.locale = locale;
176
+ }
226
177
  async getProfile(id, options = {}) {
227
178
  if (!id) throw new Error('Valid profile ID required.');
228
179
  const requestName = 'Get Profile';
@@ -231,10 +182,10 @@ class ExperienceApiClient extends src_ApiClientBase {
231
182
  const response = await this.fetch(this.constructUrl(`v2/organizations/${this.clientId}/environments/${this.environment}/profiles/${id}`, options), {
232
183
  method: 'GET'
233
184
  });
234
- const { data: { changes, experiences, profile } } = __rspack_external__contentful_optimization_api_schemas_66dcf407.ExperienceResponse.parse(await response.json());
185
+ const { data: { changes, experiences, profile } } = (0, __rspack_external__contentful_optimization_api_schemas_66dcf407.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_schemas_66dcf407.ExperienceResponse, await response.json());
235
186
  const data = {
236
187
  changes,
237
- personalizations: experiences,
188
+ selectedOptimizations: experiences,
238
189
  profile
239
190
  };
240
191
  ExperienceApiClient_logger.debug(`"${requestName}" request successfully completed`);
@@ -257,10 +208,7 @@ class ExperienceApiClient extends src_ApiClientBase {
257
208
  async createProfile({ events }, options = {}) {
258
209
  const requestName = 'Create Profile';
259
210
  ExperienceApiClient_logger.info(`Sending "${requestName}" request`);
260
- const body = {
261
- events: __rspack_external__contentful_optimization_api_schemas_66dcf407.ExperienceEventArray.parse(events),
262
- options: this.constructBodyOptions(options)
263
- };
211
+ const body = this.constructExperienceRequestBody(events, options);
264
212
  ExperienceApiClient_logger.debug(`"${requestName}" request body:`, body);
265
213
  try {
266
214
  const response = await this.makeProfileMutationRequest({
@@ -268,10 +216,10 @@ class ExperienceApiClient extends src_ApiClientBase {
268
216
  body,
269
217
  options
270
218
  });
271
- const { data: { changes, experiences, profile } } = __rspack_external__contentful_optimization_api_schemas_66dcf407.ExperienceResponse.parse(await response.json());
219
+ const { data: { changes, experiences, profile } } = (0, __rspack_external__contentful_optimization_api_schemas_66dcf407.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_schemas_66dcf407.ExperienceResponse, await response.json());
272
220
  const data = {
273
221
  changes,
274
- personalizations: experiences,
222
+ selectedOptimizations: experiences,
275
223
  profile
276
224
  };
277
225
  ExperienceApiClient_logger.debug(`"${requestName}" request successfully completed`);
@@ -287,10 +235,7 @@ class ExperienceApiClient extends src_ApiClientBase {
287
235
  if (!profileId) throw new Error('Valid profile ID required.');
288
236
  const requestName = 'Update Profile';
289
237
  ExperienceApiClient_logger.info(`Sending "${requestName}" request`);
290
- const body = {
291
- events: __rspack_external__contentful_optimization_api_schemas_66dcf407.ExperienceEventArray.parse(events),
292
- options: this.constructBodyOptions(options)
293
- };
238
+ const body = this.constructExperienceRequestBody(events, options);
294
239
  ExperienceApiClient_logger.debug(`"${requestName}" request body:`, body);
295
240
  try {
296
241
  const response = await this.makeProfileMutationRequest({
@@ -298,10 +243,10 @@ class ExperienceApiClient extends src_ApiClientBase {
298
243
  body,
299
244
  options
300
245
  });
301
- const { data: { changes, experiences, profile } } = __rspack_external__contentful_optimization_api_schemas_66dcf407.ExperienceResponse.parse(await response.json());
246
+ const { data: { changes, experiences, profile } } = (0, __rspack_external__contentful_optimization_api_schemas_66dcf407.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_schemas_66dcf407.ExperienceResponse, await response.json());
302
247
  const data = {
303
248
  changes,
304
- personalizations: experiences,
249
+ selectedOptimizations: experiences,
305
250
  profile
306
251
  };
307
252
  ExperienceApiClient_logger.debug(`"${requestName}" request successfully completed`);
@@ -325,10 +270,10 @@ class ExperienceApiClient extends src_ApiClientBase {
325
270
  async upsertManyProfiles({ events }, options = {}) {
326
271
  const requestName = 'Upsert Many Profiles';
327
272
  ExperienceApiClient_logger.info(`Sending "${requestName}" request`);
328
- const body = {
329
- events: __rspack_external__contentful_optimization_api_schemas_66dcf407.ExperienceEventArray.parse(events),
273
+ const body = (0, __rspack_external__contentful_optimization_api_schemas_66dcf407.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_schemas_66dcf407.BatchExperienceRequestData, {
274
+ events,
330
275
  options: this.constructBodyOptions(options)
331
- };
276
+ });
332
277
  ExperienceApiClient_logger.debug(`"${requestName}" request body:`, body);
333
278
  try {
334
279
  const response = await this.makeProfileMutationRequest({
@@ -339,7 +284,7 @@ class ExperienceApiClient extends src_ApiClientBase {
339
284
  ...options
340
285
  }
341
286
  });
342
- const { data: { profiles } } = __rspack_external__contentful_optimization_api_schemas_66dcf407.BatchExperienceResponse.parse(await response.json());
287
+ const { data: { profiles } } = (0, __rspack_external__contentful_optimization_api_schemas_66dcf407.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_schemas_66dcf407.BatchExperienceResponse, await response.json());
343
288
  ExperienceApiClient_logger.debug(`"${requestName}" request successfully completed`);
344
289
  return profiles;
345
290
  } catch (error) {
@@ -373,40 +318,50 @@ class ExperienceApiClient extends src_ApiClientBase {
373
318
  ];
374
319
  return bodyOptions;
375
320
  };
321
+ constructExperienceRequestBody(events, options) {
322
+ return __rspack_external__contentful_optimization_api_schemas_66dcf407.ExperienceRequestData.parse({
323
+ events: (0, __rspack_external__contentful_optimization_api_schemas_66dcf407.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_schemas_66dcf407.ExperienceEventArray, events),
324
+ options: this.constructBodyOptions(options)
325
+ });
326
+ }
376
327
  }
377
- const experience = ExperienceApiClient;
378
328
  const InsightsApiClient_logger = createScopedLogger('ApiClient:Insights');
329
+ const BEACON_FALLBACK_MESSAGE = 'beacon failed; falling back to fetch';
379
330
  const INSIGHTS_BASE_URL = 'https://ingest.insights.ninetailed.co/';
380
331
  class InsightsApiClient extends src_ApiClientBase {
381
332
  baseUrl;
382
- beaconHandler;
383
333
  constructor(config){
384
334
  super('Insights', config);
385
- const { baseUrl, beaconHandler } = config;
335
+ const { baseUrl } = config;
386
336
  this.baseUrl = baseUrl || INSIGHTS_BASE_URL;
387
- this.beaconHandler = beaconHandler;
388
337
  }
389
338
  async sendBatchEvents(batches, options = {}) {
390
- const { beaconHandler = this.beaconHandler } = options;
339
+ const { beacon } = options;
391
340
  const url = new URL(`v1/organizations/${this.clientId}/environments/${this.environment}/events`, this.baseUrl);
392
- const body = __rspack_external__contentful_optimization_api_schemas_66dcf407.BatchInsightsEventArray.parse(batches);
393
- if ('function' == typeof beaconHandler) {
394
- InsightsApiClient_logger.debug('Queueing events via beaconHandler');
395
- const beaconSuccessfullyQueued = beaconHandler(url, body);
396
- if (beaconSuccessfullyQueued) return true;
397
- InsightsApiClient_logger.warn('beaconHandler failed to queue events; events will be emitted immediately via fetch');
341
+ const urlString = url.toString();
342
+ const body = (0, __rspack_external__contentful_optimization_api_schemas_66dcf407.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_schemas_66dcf407.BatchInsightsEventArray, batches);
343
+ const serializedBody = JSON.stringify(body);
344
+ if (beacon) {
345
+ InsightsApiClient_logger.debug('Queueing events via beacon');
346
+ try {
347
+ const beaconSuccessfullyQueued = beacon(urlString, serializedBody);
348
+ if (beaconSuccessfullyQueued) return true;
349
+ InsightsApiClient_logger.warn(BEACON_FALLBACK_MESSAGE);
350
+ } catch (error) {
351
+ InsightsApiClient_logger.warn(BEACON_FALLBACK_MESSAGE, error);
352
+ }
398
353
  }
399
354
  const requestName = 'Event Batches';
400
355
  InsightsApiClient_logger.info(`Sending "${requestName}" request`);
401
356
  InsightsApiClient_logger.debug(`"${requestName}" request body:`, body);
402
357
  try {
403
- await this.fetch(url, {
358
+ await this.fetch(urlString, {
404
359
  method: 'POST',
405
360
  headers: {
406
361
  'Content-Type': 'application/json'
407
362
  },
408
- body: JSON.stringify(body),
409
- keepalive: true
363
+ body: serializedBody,
364
+ keepalive: !!beacon
410
365
  });
411
366
  InsightsApiClient_logger.debug(`"${requestName}" request successfully completed`);
412
367
  return true;
@@ -418,166 +373,28 @@ class InsightsApiClient extends src_ApiClientBase {
418
373
  }
419
374
  }
420
375
  }
421
- const insights = InsightsApiClient;
422
376
  class ApiClient {
423
377
  config;
424
378
  experience;
425
379
  insights;
426
380
  constructor(config){
427
- const { personalization, analytics, ...apiConfig } = config;
381
+ const { experience, insights, clientId, environment, fetchOptions } = config;
382
+ const apiConfig = {
383
+ clientId,
384
+ environment,
385
+ fetchOptions
386
+ };
428
387
  this.config = apiConfig;
429
- this.experience = new experience({
388
+ this.experience = new ExperienceApiClient({
430
389
  ...apiConfig,
431
- ...personalization
390
+ ...experience
432
391
  });
433
- this.insights = new insights({
392
+ this.insights = new InsightsApiClient({
434
393
  ...apiConfig,
435
- ...analytics
394
+ ...insights
436
395
  });
437
396
  }
438
397
  }
439
- const UniversalEventBuilderArgs = object({
440
- campaign: optional(__rspack_external__contentful_optimization_api_schemas_66dcf407.Campaign),
441
- locale: optional(string()),
442
- location: optional(__rspack_external__contentful_optimization_api_schemas_66dcf407.GeoLocation),
443
- page: optional(__rspack_external__contentful_optimization_api_schemas_66dcf407.Page),
444
- screen: optional(__rspack_external__contentful_optimization_api_schemas_66dcf407.Screen),
445
- userAgent: optional(string())
446
- });
447
- const ComponentViewBuilderArgs = extend(UniversalEventBuilderArgs, {
448
- componentId: string(),
449
- experienceId: optional(string()),
450
- variantIndex: optional(number()),
451
- sticky: optional(mini_boolean())
452
- });
453
- const IdentifyBuilderArgs = extend(UniversalEventBuilderArgs, {
454
- traits: optional(__rspack_external__contentful_optimization_api_schemas_66dcf407.Traits),
455
- userId: string()
456
- });
457
- const PageViewBuilderArgs = extend(UniversalEventBuilderArgs, {
458
- properties: optional(partial(__rspack_external__contentful_optimization_api_schemas_66dcf407.Page))
459
- });
460
- const ScreenViewBuilderArgs = extend(UniversalEventBuilderArgs, {
461
- name: string(),
462
- properties: __rspack_external__contentful_optimization_api_schemas_66dcf407.Properties
463
- });
464
- const TrackBuilderArgs = extend(UniversalEventBuilderArgs, {
465
- event: string(),
466
- properties: optional(prefault(__rspack_external__contentful_optimization_api_schemas_66dcf407.Properties, {}))
467
- });
468
- const DEFAULT_PAGE_PROPERTIES = {
469
- path: '',
470
- query: {},
471
- referrer: '',
472
- search: '',
473
- title: '',
474
- url: ''
475
- };
476
- class EventBuilder {
477
- app;
478
- channel;
479
- library;
480
- getLocale;
481
- getPageProperties;
482
- getUserAgent;
483
- constructor(config){
484
- const { app, channel, library, getLocale, getPageProperties, getUserAgent } = config;
485
- this.app = app;
486
- this.channel = channel;
487
- this.library = library;
488
- this.getLocale = getLocale ?? (()=>'en-US');
489
- this.getPageProperties = getPageProperties ?? (()=>DEFAULT_PAGE_PROPERTIES);
490
- this.getUserAgent = getUserAgent ?? (()=>void 0);
491
- }
492
- buildUniversalEventProperties({ campaign = {}, locale, location, page, screen, userAgent }) {
493
- const timestamp = new Date().toISOString();
494
- return {
495
- channel: this.channel,
496
- context: {
497
- app: this.app,
498
- campaign,
499
- gdpr: {
500
- isConsentGiven: true
501
- },
502
- library: this.library,
503
- locale: locale ?? this.getLocale() ?? 'en-US',
504
- location,
505
- page: page ?? this.getPageProperties(),
506
- screen,
507
- userAgent: userAgent ?? this.getUserAgent()
508
- },
509
- messageId: crypto.randomUUID(),
510
- originalTimestamp: timestamp,
511
- sentAt: timestamp,
512
- timestamp
513
- };
514
- }
515
- buildComponentView(args) {
516
- const { componentId, experienceId, variantIndex, ...universal } = ComponentViewBuilderArgs.parse(args);
517
- return {
518
- ...this.buildUniversalEventProperties(universal),
519
- type: 'component',
520
- componentType: 'Entry',
521
- componentId,
522
- experienceId,
523
- variantIndex: variantIndex ?? 0
524
- };
525
- }
526
- buildFlagView(args) {
527
- return {
528
- ...this.buildComponentView(args),
529
- componentType: 'Variable'
530
- };
531
- }
532
- buildIdentify(args) {
533
- const { traits = {}, userId, ...universal } = IdentifyBuilderArgs.parse(args);
534
- return {
535
- ...this.buildUniversalEventProperties(universal),
536
- type: 'identify',
537
- traits,
538
- userId
539
- };
540
- }
541
- buildPageView(args = {}) {
542
- const { properties = {}, ...universal } = PageViewBuilderArgs.parse(args);
543
- const pageProperties = this.getPageProperties();
544
- const merged = merge({
545
- ...pageProperties,
546
- title: pageProperties.title ?? DEFAULT_PAGE_PROPERTIES.title
547
- }, properties);
548
- const { context: { screen: _, ...universalContext }, ...universalProperties } = this.buildUniversalEventProperties(universal);
549
- const context = __rspack_external__contentful_optimization_api_schemas_66dcf407.PageEventContext.parse(universalContext);
550
- return {
551
- ...universalProperties,
552
- context,
553
- type: 'page',
554
- properties: merged
555
- };
556
- }
557
- buildScreenView(args) {
558
- const { name, properties, ...universal } = ScreenViewBuilderArgs.parse(args);
559
- const { context: { page: _, ...universalContext }, ...universalProperties } = this.buildUniversalEventProperties(universal);
560
- const context = __rspack_external__contentful_optimization_api_schemas_66dcf407.ScreenEventContext.parse(universalContext);
561
- return {
562
- ...universalProperties,
563
- context,
564
- type: 'screen',
565
- name,
566
- properties
567
- };
568
- }
569
- buildTrack(args) {
570
- const { event, properties = {}, ...universal } = TrackBuilderArgs.parse(args);
571
- return {
572
- ...this.buildUniversalEventProperties(universal),
573
- type: 'track',
574
- event,
575
- properties
576
- };
577
- }
578
- }
579
- const builders_EventBuilder = EventBuilder;
580
- export * from "@contentful/optimization-api-schemas";
581
- export { ApiClient, DEFAULT_PAGE_PROPERTIES, EXPERIENCE_BASE_URL, INSIGHTS_BASE_URL, builders_EventBuilder as EventBuilder };
398
+ export { ApiClient, EXPERIENCE_BASE_URL, ExperienceApiClient, INSIGHTS_BASE_URL, InsightsApiClient, createProtectedFetchMethod, createRetryFetchMethod, createTimeoutFetchMethod };
582
399
 
583
400
  //# sourceMappingURL=index.mjs.map