coveo.analytics 2.30.55 → 2.31.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.
- package/README.md +37 -43
- package/dist/browser.mjs +525 -357
- package/dist/coveoua.browser.js +1 -1
- package/dist/coveoua.browser.js.map +1 -1
- package/dist/coveoua.debug.js +559 -359
- package/dist/coveoua.debug.js.map +1 -1
- package/dist/coveoua.js +1 -1
- package/dist/coveoua.js.map +1 -1
- package/dist/definitions/client/analytics.d.ts +3 -2
- package/dist/definitions/client/runtimeEnvironment.d.ts +1 -1
- package/dist/definitions/donottrack.d.ts +1 -0
- package/dist/definitions/react-native/index.d.ts +1 -1
- package/dist/definitions/searchPage/searchPageClient.d.ts +3 -1
- package/dist/definitions/searchPage/searchPageEvents.d.ts +6 -0
- package/dist/definitions/version.d.ts +1 -1
- package/dist/library.cjs +15367 -3699
- package/dist/library.es.js +525 -357
- package/dist/library.js +15367 -3699
- package/dist/library.mjs +15367 -3699
- package/dist/react-native.es.js +646 -460
- package/modules/package.json +9 -9
- package/package.json +60 -91
- package/react-native/package.json +7 -7
- package/src/caseAssist/caseAssistActions.ts +51 -50
- package/src/caseAssist/caseAssistClient.spec.ts +328 -297
- package/src/caseAssist/caseAssistClient.ts +201 -185
- package/src/client/analytics.spec.ts +724 -703
- package/src/client/analytics.ts +677 -602
- package/src/client/analyticsBeaconClient.spec.ts +195 -188
- package/src/client/analyticsBeaconClient.ts +99 -88
- package/src/client/analyticsFetchClient.ts +77 -61
- package/src/client/analyticsRequestClient.ts +17 -17
- package/src/client/location.ts +3 -3
- package/src/client/measurementProtocolMapper.ts +54 -45
- package/src/client/measurementProtocolMapping/baseMeasurementProtocolMapper.ts +48 -44
- package/src/client/measurementProtocolMapping/commerceMeasurementProtocolMapper.ts +133 -121
- package/src/client/measurementProtocolMapping/serviceMeasurementProtocolMapper.ts +17 -17
- package/src/client/noopAnalytics.ts +80 -68
- package/src/client/runtimeEnvironment.ts +50 -41
- package/src/client/utils.spec.ts +112 -97
- package/src/client/utils.ts +39 -39
- package/src/cookieutils.spec.ts +59 -0
- package/src/cookieutils.ts +40 -39
- package/src/coveoua/browser.ts +14 -12
- package/src/coveoua/library.ts +4 -4
- package/src/coveoua/plugins.ts +36 -34
- package/src/coveoua/simpleanalytics.spec.ts +467 -452
- package/src/coveoua/simpleanalytics.ts +146 -140
- package/src/detector.ts +17 -17
- package/src/donottrack.spec.ts +199 -121
- package/src/donottrack.ts +31 -8
- package/src/events.ts +86 -79
- package/src/formatting/format-array-for-coveo-custom-data.spec.ts +13 -12
- package/src/formatting/format-array-for-coveo-custom-data.ts +18 -18
- package/src/formatting/format-omnibox-metadata.ts +16 -12
- package/src/history.spec.ts +197 -195
- package/src/history.ts +143 -133
- package/src/hook/addDefaultValues.ts +13 -8
- package/src/hook/enhanceViewEvent.ts +17 -17
- package/src/insight/insightClient.spec.ts +1848 -1717
- package/src/insight/insightClient.ts +866 -761
- package/src/insight/insightEvents.ts +57 -56
- package/src/plugins/BasePlugin.ts +125 -121
- package/src/plugins/ec.spec.ts +457 -429
- package/src/plugins/ec.ts +202 -199
- package/src/plugins/link.spec.ts +183 -159
- package/src/plugins/link.ts +88 -85
- package/src/plugins/svc.spec.ts +161 -155
- package/src/plugins/svc.ts +93 -91
- package/src/react-native/index.ts +5 -1
- package/src/react-native/react-native-runtime.ts +33 -33
- package/src/react-native/react-native-utils.ts +1 -1
- package/src/react-native/react-native.spec.ts +22 -21
- package/src/searchPage/searchPageClient.spec.ts +1944 -1766
- package/src/searchPage/searchPageClient.ts +1261 -1029
- package/src/searchPage/searchPageEvents.ts +529 -500
- package/src/storage.spec.ts +51 -51
- package/src/storage.ts +47 -47
- package/dist/definitions/bundle/browser-fetch.d.ts +0 -1
- package/dist/definitions/src/coveoua/browser.d.ts +0 -6
- package/dist/definitions/src/coveoua/headless.d.ts +0 -6
- package/dist/definitions/src/coveoua/library.d.ts +0 -17
- package/dist/definitions/src/coveoua/plugins.d.ts +0 -10
- package/dist/definitions/src/coveoua/simpleanalytics.d.ts +0 -33
- package/dist/definitions/src/react-native/index.d.ts +0 -3
- package/dist/definitions/src/react-native/react-native-runtime.d.ts +0 -19
package/src/plugins/ec.ts
CHANGED
|
@@ -1,241 +1,244 @@
|
|
|
1
1
|
import {EventType} from '../events';
|
|
2
2
|
import {v4 as uuidv4} from 'uuid';
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
convertProductToMeasurementProtocol,
|
|
5
|
+
convertImpressionListToMeasurementProtocol,
|
|
6
6
|
} from '../client/measurementProtocolMapping/commerceMeasurementProtocolMapper';
|
|
7
7
|
import {BasePlugin, BasePluginEventTypes, PluginClass, PluginOptions} from './BasePlugin';
|
|
8
8
|
import {coerceToNumber} from '../client/utils';
|
|
9
9
|
|
|
10
10
|
export const ECPluginEventTypes = {
|
|
11
|
-
|
|
11
|
+
...BasePluginEventTypes,
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
const allECEventTypes = Object.keys(ECPluginEventTypes).map(
|
|
15
|
-
|
|
15
|
+
(key) => ECPluginEventTypes[key as keyof typeof ECPluginEventTypes]
|
|
16
16
|
);
|
|
17
17
|
|
|
18
18
|
// From https://stackoverflow.com/a/49725198/497731
|
|
19
19
|
type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> &
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
{
|
|
21
|
+
[K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>;
|
|
22
|
+
}[Keys];
|
|
23
23
|
|
|
24
24
|
export type CustomValues = {
|
|
25
|
-
|
|
25
|
+
[key: string]: string | number | boolean;
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
export interface CoveoExtensionProperties {
|
|
29
|
-
|
|
29
|
+
group?: string;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export interface ProductProperties extends CoveoExtensionProperties {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
33
|
+
id?: string;
|
|
34
|
+
name?: string;
|
|
35
|
+
brand?: string;
|
|
36
|
+
category?: string;
|
|
37
|
+
variant?: string;
|
|
38
|
+
price?: number;
|
|
39
|
+
quantity?: number;
|
|
40
|
+
coupon?: string;
|
|
41
|
+
position?: number;
|
|
42
|
+
custom?: CustomValues;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
export type Product = RequireAtLeastOne<ProductProperties, 'id' | 'name'>;
|
|
46
46
|
|
|
47
47
|
export interface ImpressionProperties extends CoveoExtensionProperties {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
48
|
+
id?: string;
|
|
49
|
+
name?: string;
|
|
50
|
+
list?: string;
|
|
51
|
+
brand?: string;
|
|
52
|
+
category?: string;
|
|
53
|
+
variant?: string;
|
|
54
|
+
position?: number;
|
|
55
|
+
price?: number;
|
|
56
|
+
custom?: CustomValues;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
export type Impression = RequireAtLeastOne<ImpressionProperties, 'id' | 'name'>;
|
|
60
60
|
export type BaseImpression = Omit<Impression, 'list'>;
|
|
61
61
|
export interface ImpressionList {
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
listName?: string;
|
|
63
|
+
impressions: BaseImpression[];
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
export class ECPlugin extends BasePlugin {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
67
|
+
public static readonly Id = 'ec';
|
|
68
|
+
private products: Product[] = [];
|
|
69
|
+
private impressions: Impression[] = [];
|
|
70
|
+
|
|
71
|
+
constructor({client, uuidGenerator = uuidv4}: PluginOptions) {
|
|
72
|
+
super({client, uuidGenerator});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public getApi(name: string): Function | null {
|
|
76
|
+
const superCall: Function | null = super.getApi(name);
|
|
77
|
+
if (superCall !== null) return superCall;
|
|
78
|
+
switch (name) {
|
|
79
|
+
case 'addProduct':
|
|
80
|
+
return this.addProduct;
|
|
81
|
+
case 'addImpression':
|
|
82
|
+
return this.addImpression;
|
|
83
|
+
default:
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
protected addHooks(): void {
|
|
89
|
+
this.addHooksForPageView();
|
|
90
|
+
this.addHooksForEvent();
|
|
91
|
+
this.addHooksForECEvents();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
addProduct(product: Product) {
|
|
95
|
+
this.products.push(product);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
addImpression(impression: Impression) {
|
|
99
|
+
this.impressions.push(impression);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
protected clearPluginData() {
|
|
103
|
+
this.products = [];
|
|
104
|
+
this.impressions = [];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private addHooksForECEvents() {
|
|
108
|
+
this.client.registerBeforeSendEventHook((eventType, ...[payload]) => {
|
|
109
|
+
return allECEventTypes.indexOf(eventType) !== -1
|
|
110
|
+
? this.addECDataToPayload(eventType, payload)
|
|
111
|
+
: payload;
|
|
112
|
+
});
|
|
113
|
+
this.client.registerAfterSendEventHook((eventType, ...[payload]) => {
|
|
114
|
+
if (allECEventTypes.indexOf(eventType) !== -1) {
|
|
115
|
+
this.updateLocationInformation(eventType, payload);
|
|
116
|
+
}
|
|
117
|
+
return payload;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private addHooksForPageView() {
|
|
122
|
+
this.client.addEventTypeMapping(ECPluginEventTypes.pageview, {
|
|
123
|
+
newEventType: EventType.collect,
|
|
124
|
+
variableLengthArgumentsNames: ['page'],
|
|
125
|
+
addVisitorIdParameter: true,
|
|
126
|
+
usesMeasurementProtocol: true,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private addHooksForEvent() {
|
|
131
|
+
this.client.addEventTypeMapping(ECPluginEventTypes.event, {
|
|
132
|
+
newEventType: EventType.collect,
|
|
133
|
+
variableLengthArgumentsNames: ['eventCategory', 'eventAction', 'eventLabel', 'eventValue'],
|
|
134
|
+
addVisitorIdParameter: true,
|
|
135
|
+
usesMeasurementProtocol: true,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private addECDataToPayload(eventType: string, payload: any) {
|
|
140
|
+
const ecPayload = {
|
|
141
|
+
...this.getLocationInformation(eventType, payload),
|
|
142
|
+
...this.getDefaultContextInformation(eventType),
|
|
143
|
+
...(this.action ? {action: this.action} : {}),
|
|
144
|
+
...(this.actionData || {}),
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const productPayload = this.getProductPayload();
|
|
148
|
+
const impressionPayload = this.getImpressionPayload();
|
|
149
|
+
|
|
150
|
+
this.clearData();
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
...impressionPayload,
|
|
154
|
+
...productPayload,
|
|
155
|
+
...ecPayload,
|
|
156
|
+
...payload,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private getProductPayload() {
|
|
161
|
+
return this.products
|
|
162
|
+
.map((product) => this.assureProductValidity(product))
|
|
163
|
+
.reduce((newPayload, product, index) => {
|
|
164
|
+
return {
|
|
165
|
+
...newPayload,
|
|
166
|
+
...convertProductToMeasurementProtocol(this.convertNumberTypes(product), index),
|
|
143
167
|
};
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
168
|
+
}, {});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
private convertNumberTypes(product: Product): Product {
|
|
172
|
+
let updatedProduct: Product = {...product};
|
|
173
|
+
if ('quantity' in updatedProduct) {
|
|
174
|
+
updatedProduct.quantity = coerceToNumber(updatedProduct.quantity);
|
|
175
|
+
}
|
|
176
|
+
if ('position' in updatedProduct) {
|
|
177
|
+
updatedProduct.position = coerceToNumber(updatedProduct.position);
|
|
178
|
+
}
|
|
179
|
+
return updatedProduct;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
private getImpressionPayload() {
|
|
183
|
+
const impressionsByList = this.getImpressionsByList();
|
|
184
|
+
return impressionsByList
|
|
185
|
+
.map(
|
|
186
|
+
({impressions, ...rest}) =>
|
|
187
|
+
({
|
|
188
|
+
...rest,
|
|
189
|
+
impressions: impressions.map((baseImpression) =>
|
|
190
|
+
this.assureBaseImpressionValidity(baseImpression)
|
|
191
|
+
),
|
|
192
|
+
}) as ImpressionList
|
|
193
|
+
)
|
|
194
|
+
.reduce((newPayload, impressionList, index) => {
|
|
150
195
|
return {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
...ecPayload,
|
|
154
|
-
...payload,
|
|
196
|
+
...newPayload,
|
|
197
|
+
...convertImpressionListToMeasurementProtocol(impressionList, index, 'pi'),
|
|
155
198
|
};
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
private assureProductValidity(product: Product) {
|
|
201
|
-
const {position, ...productRest} = product;
|
|
202
|
-
if (position !== undefined && position < 1) {
|
|
203
|
-
console.warn(
|
|
204
|
-
`The position for product '${product.name || product.id}' must be greater ` + `than 0 when provided.`,
|
|
205
|
-
);
|
|
206
|
-
|
|
207
|
-
return productRest;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
return product;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
private assureBaseImpressionValidity(baseImpression: BaseImpression) {
|
|
214
|
-
const {position, ...baseImpressionRest} = baseImpression;
|
|
215
|
-
if (position !== undefined && position < 1) {
|
|
216
|
-
console.warn(
|
|
217
|
-
`The position for impression '${baseImpression.name || baseImpression.id}'` +
|
|
218
|
-
` must be greater than 0 when provided.`,
|
|
219
|
-
);
|
|
220
|
-
|
|
221
|
-
return baseImpressionRest;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
return baseImpression;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
private getImpressionsByList() {
|
|
228
|
-
return this.impressions.reduce((lists, impression) => {
|
|
229
|
-
const {list: listName, ...baseImpression} = impression;
|
|
230
|
-
const list = lists.find((list) => list.listName === listName);
|
|
231
|
-
if (list) {
|
|
232
|
-
list.impressions.push(baseImpression);
|
|
233
|
-
} else {
|
|
234
|
-
lists.push({listName: listName, impressions: [baseImpression]});
|
|
235
|
-
}
|
|
236
|
-
return lists;
|
|
237
|
-
}, [] as ImpressionList[]);
|
|
238
|
-
}
|
|
199
|
+
}, {});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
private assureProductValidity(product: Product) {
|
|
203
|
+
const {position, ...productRest} = product;
|
|
204
|
+
if (position !== undefined && position < 1) {
|
|
205
|
+
console.warn(
|
|
206
|
+
`The position for product '${product.name || product.id}' must be greater ` +
|
|
207
|
+
`than 0 when provided.`
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
return productRest;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return product;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
private assureBaseImpressionValidity(baseImpression: BaseImpression) {
|
|
217
|
+
const {position, ...baseImpressionRest} = baseImpression;
|
|
218
|
+
if (position !== undefined && position < 1) {
|
|
219
|
+
console.warn(
|
|
220
|
+
`The position for impression '${baseImpression.name || baseImpression.id}'` +
|
|
221
|
+
` must be greater than 0 when provided.`
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
return baseImpressionRest;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return baseImpression;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private getImpressionsByList() {
|
|
231
|
+
return this.impressions.reduce((lists, impression) => {
|
|
232
|
+
const {list: listName, ...baseImpression} = impression;
|
|
233
|
+
const list = lists.find((list) => list.listName === listName);
|
|
234
|
+
if (list) {
|
|
235
|
+
list.impressions.push(baseImpression);
|
|
236
|
+
} else {
|
|
237
|
+
lists.push({listName: listName, impressions: [baseImpression]});
|
|
238
|
+
}
|
|
239
|
+
return lists;
|
|
240
|
+
}, [] as ImpressionList[]);
|
|
241
|
+
}
|
|
239
242
|
}
|
|
240
243
|
|
|
241
244
|
export const EC: PluginClass = ECPlugin;
|