@adobe/spacecat-shared-rum-api-client 2.38.6 → 2.38.8
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 +19 -0
- package/package.json +1 -1
- package/src/common/traffic.js +76 -32
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
# [@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)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **traffic-attribution:** limit vendors per source ([#1079](https://github.com/adobe/spacecat-shared/issues/1079)) ([9165913](https://github.com/adobe/spacecat-shared/commit/9165913f379a00df409fe86961ba5df1f5a2a840))
|
|
7
|
+
|
|
8
|
+
# [@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)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **traffic-attribution:** handle direct referrers from rum-distiller ([#1061](https://github.com/adobe/spacecat-shared/issues/1061)) ([99b1262](https://github.com/adobe/spacecat-shared/commit/99b1262638c978579770f63715ed1dd5090bffa4))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Reverts
|
|
17
|
+
|
|
18
|
+
* Revert "fix(traffic-attribution): handle non standard referrers ([#1040](https://github.com/adobe/spacecat-shared/issues/1040))" ([3686145](https://github.com/adobe/spacecat-shared/commit/3686145d16b0cc39d0da88c0bd2ca10dc249f93c))
|
|
19
|
+
|
|
1
20
|
# [@adobe/spacecat-shared-rum-api-client-v2.38.6](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-rum-api-client-v2.38.5...@adobe/spacecat-shared-rum-api-client-v2.38.6) (2025-10-28)
|
|
2
21
|
|
|
3
22
|
|
package/package.json
CHANGED
package/src/common/traffic.js
CHANGED
|
@@ -26,9 +26,17 @@ import URI from 'urijs';
|
|
|
26
26
|
*/
|
|
27
27
|
export function getSecondLevelDomain(url) {
|
|
28
28
|
if (!hasText(url)) return url;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
if (url === '(direct)') return '';
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
const uri = new URI(prependSchema(url));
|
|
33
|
+
const tld = uri.tld();
|
|
34
|
+
return uri.hostname().split(`.${tld}`)[0];
|
|
35
|
+
/* c8 ignore next 4 */
|
|
36
|
+
} catch (error) {
|
|
37
|
+
// future-proof for the cases where url cannot be parsed for some reason
|
|
38
|
+
return url;
|
|
39
|
+
}
|
|
32
40
|
}
|
|
33
41
|
|
|
34
42
|
/*
|
|
@@ -138,27 +146,61 @@ const not = (truth) => (text) => {
|
|
|
138
146
|
|
|
139
147
|
const notEmpty = (text) => hasText(text);
|
|
140
148
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
149
|
+
// overrides
|
|
150
|
+
const OVERRIDES = [
|
|
151
|
+
{ when: (ctx) => (ctx.utmSource || '').toLowerCase() === 'chatgpt.com', set: { type: 'earned', category: 'llm', vendor: 'openai' } },
|
|
152
|
+
];
|
|
144
153
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
{
|
|
148
|
-
|
|
149
|
-
|
|
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
|
|
150
167
|
},
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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
|
|
155
175
|
},
|
|
156
|
-
|
|
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 '';
|
|
157
196
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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 : '';
|
|
162
204
|
}
|
|
163
205
|
|
|
164
206
|
/*
|
|
@@ -275,23 +317,25 @@ export function classifyTrafficSource(url, referrer, utmSource, utmMedium, track
|
|
|
275
317
|
&& rule.utmMedium(sanitize(utmMedium))
|
|
276
318
|
&& rule.tracking(trackingParams)
|
|
277
319
|
));
|
|
278
|
-
|
|
279
|
-
|
|
320
|
+
let { type, category } = match;
|
|
321
|
+
let vendor = classifyVendor(referrerDomain, utmSource, utmMedium);
|
|
280
322
|
|
|
281
|
-
|
|
323
|
+
// apply overrides
|
|
324
|
+
const overridden = applyOverrides(
|
|
282
325
|
{ type, category, vendor },
|
|
283
|
-
{
|
|
284
|
-
utmSourceRaw: utmSource,
|
|
285
|
-
utmSource: sanitize(utmSource),
|
|
286
|
-
utmMedium: sanitize(utmMedium),
|
|
287
|
-
referrerDomain,
|
|
288
|
-
},
|
|
326
|
+
{ utmSource, utmMedium, referrerDomain },
|
|
289
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);
|
|
290
334
|
|
|
291
335
|
return {
|
|
292
|
-
type
|
|
293
|
-
category
|
|
294
|
-
vendor:
|
|
336
|
+
type,
|
|
337
|
+
category,
|
|
338
|
+
vendor: validatedVendor,
|
|
295
339
|
};
|
|
296
340
|
}
|
|
297
341
|
|