@adobe/spacecat-shared-rum-api-client 2.38.7 → 2.38.9

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/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # [@adobe/spacecat-shared-rum-api-client-v2.38.9](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-rum-api-client-v2.38.8...@adobe/spacecat-shared-rum-api-client-v2.38.9) (2025-11-04)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **deps:** update dependency @adobe/helix-universal to v5.3.0 ([#1091](https://github.com/adobe/spacecat-shared/issues/1091)) ([13cbc72](https://github.com/adobe/spacecat-shared/commit/13cbc721f67c066948337faa6c6a4ea5b0c5ec9a))
7
+
8
+ # [@adobe/spacecat-shared-rum-api-client-v2.38.8](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-rum-api-client-v2.38.7...@adobe/spacecat-shared-rum-api-client-v2.38.8) (2025-10-31)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **traffic-attribution:** limit vendors per source ([#1079](https://github.com/adobe/spacecat-shared/issues/1079)) ([9165913](https://github.com/adobe/spacecat-shared/commit/9165913f379a00df409fe86961ba5df1f5a2a840))
14
+
1
15
  # [@adobe/spacecat-shared-rum-api-client-v2.38.7](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-rum-api-client-v2.38.6...@adobe/spacecat-shared-rum-api-client-v2.38.7) (2025-10-29)
2
16
 
3
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/spacecat-shared-rum-api-client",
3
- "version": "2.38.7",
3
+ "version": "2.38.9",
4
4
  "description": "Shared modules of the Spacecat Services - Rum API client",
5
5
  "type": "module",
6
6
  "engines": {
@@ -37,7 +37,7 @@
37
37
  "dependencies": {
38
38
  "@adobe/fetch": "4.2.3",
39
39
  "@adobe/helix-shared-wrap": "2.0.2",
40
- "@adobe/helix-universal": "5.2.3",
40
+ "@adobe/helix-universal": "5.3.0",
41
41
  "@adobe/rum-distiller": "1.20.8",
42
42
  "@adobe/spacecat-shared-utils": "1.66.0",
43
43
  "aws4": "1.13.2",
@@ -146,27 +146,61 @@ const not = (truth) => (text) => {
146
146
 
147
147
  const notEmpty = (text) => hasText(text);
148
148
 
149
- /*
150
- * --------- ENFORCEMENTS ----------------
151
- */
149
+ // overrides
150
+ const OVERRIDES = [
151
+ { when: (ctx) => (ctx.utmSource || '').toLowerCase() === 'chatgpt.com', set: { type: 'earned', category: 'llm', vendor: 'openai' } },
152
+ ];
152
153
 
153
- const ENFORCEMENTS = [
154
- // vendors 'openai', 'claude', and 'perplexity' can only be earned/llm
155
- {
156
- when: (state) => state.vendor === 'openai' || state.vendor === 'claude' || state.vendor === 'perplexity',
157
- enforce: (state) => ({ ...state, type: 'earned', category: 'llm' }),
154
+ function applyOverrides(classification, context) {
155
+ const override = OVERRIDES.find((rule) => rule.when(context));
156
+ return override ? { ...classification, ...override.set } : classification;
157
+ }
158
+
159
+ // allowed known vendors per category
160
+ const ALLOWED_VENDORS = {
161
+ earned: {
162
+ llm: ['openai', 'claude', 'perplexity', 'microsoft', 'google'],
163
+ search: ['google', 'bing', 'yahoo', 'yandex', 'baidu', 'duckduckgo', 'brave', 'ecosia', 'aol'],
164
+ social: null, // any vendor allowed
165
+ video: ['youtube', 'vimeo', 'twitch', 'tiktok', 'dailymotion'],
166
+ referral: null, // any vendor allowed
158
167
  },
159
- // if utm_source=chatgpt.com, force earned/llm and vendor=openai
160
- {
161
- when: (state, ctx) => (ctx.utmSourceRaw || '').toLowerCase() === 'chatgpt.com',
162
- enforce: (state) => ({ ...state, type: 'earned', category: 'llm', vendor: 'openai' }),
168
+ paid: {
169
+ search: ['google', 'bing', 'yahoo', 'yandex', 'baidu', 'microsoft'],
170
+ social: null, // any vendor allowed
171
+ video: ['youtube', 'vimeo', 'twitch', 'dailymotion'],
172
+ display: null, // any vendor allowed
173
+ affiliate: null, // any vendor allowed
174
+ uncategorized: null, // any vendor allowed
163
175
  },
164
- ];
176
+ owned: {
177
+ direct: ['direct'],
178
+ internal: null, // any vendor allowed
179
+ email: null, // any vendor allowed
180
+ sms: null, // any vendor allowed
181
+ qr: null, // any vendor allowed
182
+ push: null, // any vendor allowed
183
+ uncategorized: null, // any vendor allowed
184
+ },
185
+ };
186
+
187
+ /**
188
+ * Validates if a vendor is allowed for the given type/category combination.
189
+ * @param {string} type - Traffic type (earned, paid, owned)
190
+ * @param {string} category - Traffic category (llm, search, social, etc.)
191
+ * @param {string} vendor - Vendor name to validate
192
+ * @returns {string} The vendor if allowed, empty string otherwise
193
+ */
194
+ function validateVendor(type, category, vendor) {
195
+ if (!vendor) return '';
165
196
 
166
- function applyEnforcements(initialState, context) {
167
- return ENFORCEMENTS
168
- .reduce((acc, rule) => (
169
- rule.when(acc, context) ? rule.enforce(acc, context) : acc), initialState);
197
+ const allowedVendors = ALLOWED_VENDORS[type]?.[category];
198
+
199
+ // null/undefined means any vendor is allowed
200
+ if (!allowedVendors) return vendor;
201
+
202
+ // Check if vendor is in the allowed list
203
+ return allowedVendors.includes(vendor) ? vendor : '';
170
204
  }
171
205
 
172
206
  /*
@@ -283,23 +317,25 @@ export function classifyTrafficSource(url, referrer, utmSource, utmMedium, track
283
317
  && rule.utmMedium(sanitize(utmMedium))
284
318
  && rule.tracking(trackingParams)
285
319
  ));
286
- const { type, category } = match;
287
- const vendor = classifyVendor(referrerDomain, utmSource, utmMedium);
320
+ let { type, category } = match;
321
+ let vendor = classifyVendor(referrerDomain, utmSource, utmMedium);
288
322
 
289
- const enforced = applyEnforcements(
323
+ // apply overrides
324
+ const overridden = applyOverrides(
290
325
  { type, category, vendor },
291
- {
292
- utmSourceRaw: utmSource,
293
- utmSource: sanitize(utmSource),
294
- utmMedium: sanitize(utmMedium),
295
- referrerDomain,
296
- },
326
+ { utmSource, utmMedium, referrerDomain },
297
327
  );
328
+ type = overridden.type;
329
+ category = overridden.category;
330
+ vendor = overridden.vendor;
331
+
332
+ // validate vendor against allowed vendors for this type/category
333
+ const validatedVendor = validateVendor(type, category, vendor);
298
334
 
299
335
  return {
300
- type: enforced.type,
301
- category: enforced.category,
302
- vendor: enforced.vendor,
336
+ type,
337
+ category,
338
+ vendor: validatedVendor,
303
339
  };
304
340
  }
305
341