coveo.analytics 2.26.6 → 2.27.1

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 (68) hide show
  1. package/dist/coveoua.browser.js +1 -1
  2. package/dist/coveoua.browser.js.map +1 -1
  3. package/dist/coveoua.debug.js +4035 -4009
  4. package/dist/coveoua.debug.js.map +1 -1
  5. package/dist/coveoua.js +1 -1
  6. package/dist/coveoua.js.map +1 -1
  7. package/dist/definitions/bundle/browser-fetch.d.ts +1 -1
  8. package/dist/definitions/caseAssist/caseAssistActions.d.ts +76 -76
  9. package/dist/definitions/caseAssist/caseAssistClient.d.ts +28 -28
  10. package/dist/definitions/client/analytics.d.ts +116 -116
  11. package/dist/definitions/client/analyticsBeaconClient.d.ts +14 -14
  12. package/dist/definitions/client/analyticsFetchClient.d.ts +11 -11
  13. package/dist/definitions/client/analyticsRequestClient.d.ts +24 -24
  14. package/dist/definitions/client/location.d.ts +1 -1
  15. package/dist/definitions/client/measurementProtocolMapper.d.ts +7 -7
  16. package/dist/definitions/client/measurementProtocolMapping/baseMeasurementProtocolMapper.d.ts +3 -3
  17. package/dist/definitions/client/measurementProtocolMapping/commerceMeasurementProtocolMapper.d.ts +10 -10
  18. package/dist/definitions/client/measurementProtocolMapping/serviceMeasurementProtocolMapper.d.ts +6 -6
  19. package/dist/definitions/client/noopAnalytics.d.ts +25 -25
  20. package/dist/definitions/client/runtimeEnvironment.d.ts +23 -23
  21. package/dist/definitions/client/token.d.ts +1 -1
  22. package/dist/definitions/client/utils.d.ts +3 -2
  23. package/dist/definitions/cookieutils.d.ts +5 -5
  24. package/dist/definitions/coveoua/browser.d.ts +6 -6
  25. package/dist/definitions/coveoua/headless.d.ts +6 -6
  26. package/dist/definitions/coveoua/library.d.ts +17 -13
  27. package/dist/definitions/coveoua/plugins.d.ts +10 -10
  28. package/dist/definitions/coveoua/simpleanalytics.d.ts +31 -31
  29. package/dist/definitions/detector.d.ts +9 -9
  30. package/dist/definitions/donottrack.d.ts +2 -2
  31. package/dist/definitions/events.d.ts +113 -113
  32. package/dist/definitions/formatting/format-array-for-coveo-custom-data.d.ts +1 -1
  33. package/dist/definitions/formatting/format-omnibox-metadata.d.ts +2 -2
  34. package/dist/definitions/history.d.ts +33 -33
  35. package/dist/definitions/hook/addDefaultValues.d.ts +2 -2
  36. package/dist/definitions/hook/enhanceViewEvent.d.ts +2 -2
  37. package/dist/definitions/insight/insightClient.d.ts +81 -81
  38. package/dist/definitions/insight/insightEvents.d.ts +50 -50
  39. package/dist/definitions/plugins/BasePlugin.d.ts +58 -58
  40. package/dist/definitions/plugins/ec.d.ts +67 -66
  41. package/dist/definitions/plugins/link.d.ts +21 -21
  42. package/dist/definitions/plugins/svc.d.ts +32 -32
  43. package/dist/definitions/react-native/index.d.ts +3 -3
  44. package/dist/definitions/react-native/react-native-runtime.d.ts +18 -18
  45. package/dist/definitions/react-native/react-native-utils.d.ts +2 -2
  46. package/dist/definitions/searchPage/searchPageClient.d.ts +188 -188
  47. package/dist/definitions/searchPage/searchPageEvents.d.ts +181 -181
  48. package/dist/definitions/src/coveoua/browser.d.ts +6 -6
  49. package/dist/definitions/src/coveoua/headless.d.ts +6 -6
  50. package/dist/definitions/src/coveoua/library.d.ts +17 -13
  51. package/dist/definitions/src/coveoua/plugins.d.ts +10 -10
  52. package/dist/definitions/src/coveoua/simpleanalytics.d.ts +31 -31
  53. package/dist/definitions/src/react-native/index.d.ts +3 -3
  54. package/dist/definitions/src/react-native/react-native-runtime.d.ts +18 -18
  55. package/dist/definitions/storage.d.ts +24 -24
  56. package/dist/definitions/version.d.ts +1 -1
  57. package/dist/library.es.js +2629 -2629
  58. package/dist/library.js +6739 -6722
  59. package/dist/react-native.es.js +2644 -2644
  60. package/package.json +24 -25
  61. package/src/client/analyticsBeaconClient.spec.ts +3 -3
  62. package/src/client/utils.ts +11 -0
  63. package/src/coveoua/library.ts +5 -0
  64. package/src/coveoua/simpleanalytics.ts +3 -0
  65. package/src/plugins/ec.spec.ts +61 -19
  66. package/src/plugins/ec.ts +13 -1
  67. package/src/react-native/react-native.spec.ts +2 -2
  68. package/dist/definitions/src/plugins/ec.d.ts +0 -66
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coveo.analytics",
3
- "version": "2.26.6",
3
+ "version": "2.27.1",
4
4
  "description": "📈 Coveo analytics client (node and browser compatible) ",
5
5
  "main": "dist/library.js",
6
6
  "module": "dist/library.es.js",
@@ -28,38 +28,37 @@
28
28
  "react-native-get-random-values": "^1.8.0"
29
29
  },
30
30
  "devDependencies": {
31
- "@rollup/plugin-alias": "^3.1.2",
32
- "@rollup/plugin-commonjs": "^19.0.0",
33
- "@rollup/plugin-json": "^4.1.0",
34
- "@rollup/plugin-node-resolve": "^13.0.0",
31
+ "@rollup/plugin-alias": "^5.0.0",
32
+ "@rollup/plugin-commonjs": "^24.1.0",
33
+ "@rollup/plugin-json": "^6.0.0",
34
+ "@rollup/plugin-node-resolve": "^15.0.2",
35
35
  "@rollup/plugin-replace": "^5.0.2",
36
- "@types/fetch-mock": "^7.3.2",
37
- "@types/jest": "^25.1.1",
38
- "@types/jsdom": "^12.2.4",
36
+ "@rollup/plugin-terser": "^0.4.1",
37
+ "@types/fetch-mock": "^7.3.5",
38
+ "@types/jest": "^29.1.0",
39
+ "@types/jsdom": "^21.1.1",
39
40
  "@types/mime": "0.0.29",
40
41
  "@types/node": "^6.0.45",
41
42
  "@types/uuid": "^9.0.0",
42
- "babel-core": "^6.17.0",
43
- "babel-loader": "^7.1.4",
44
- "babel-preset-es2015": "^6.16.0",
45
- "babel-register": "^6.24.1",
46
- "coveralls": "^3.0.3",
47
- "exports-loader": "0.6.3",
48
- "fetch-mock": "^9.0.0-beta.2",
43
+ "@babel/core": "^7.19.6",
44
+ "@babel/register": "^7.21.0",
45
+ "@babel/preset-env": "7.21.4",
46
+ "coveralls": "^3.1.1",
47
+ "exports-loader": "0.6.4",
48
+ "fetch-mock": "^9.11.0",
49
49
  "husky": "^4.3.0",
50
- "jest": "^25.1.0",
51
- "jsdom": "^15.0.0",
52
- "lint-staged": "^10.5.1",
53
- "prettier": "2.1.2",
50
+ "jest": "^29.1.0",
51
+ "jsdom": "^21.1.1",
52
+ "jest-environment-jsdom": "^29.5.0",
53
+ "lint-staged": "^13.2.1",
54
+ "prettier": "^2.8.7",
54
55
  "rimraf": "^3.0.2",
55
- "rollup": "^2.50.6",
56
+ "rollup": "^3.20.2",
56
57
  "rollup-plugin-serve": "^1.0.1",
57
- "rollup-plugin-terser": "^7.0.2",
58
- "rollup-plugin-typescript2": "^0.27.0",
58
+ "rollup-plugin-typescript2": "^0.34.0",
59
59
  "stylelint": "^13.6.1",
60
- "ts-jest": "^25.2.0",
61
- "tsjs": "4.2.1",
62
- "typescript": "^3.8.3"
60
+ "ts-jest": "^29.1.0",
61
+ "typescript": "^5.0.4"
63
62
  },
64
63
  "overrides": {
65
64
  "plist": "3.0.5"
@@ -39,7 +39,7 @@ describe('AnalyticsBeaconClient', () => {
39
39
 
40
40
  expect(sendBeaconMock).toHaveBeenCalledWith(
41
41
  `${baseUrl}/analytics/custom?access_token=👛&visitorId=${currentVisitorId}&discardVisitInfo=true`,
42
- jasmine.anything()
42
+ expect.anything()
43
43
  );
44
44
  expect(await getSendBeaconFirstCallBlobArgument()).toBe(`customEvent=${encodeURIComponent(`{"wow":"ok"}`)}`);
45
45
  });
@@ -63,7 +63,7 @@ describe('AnalyticsBeaconClient', () => {
63
63
 
64
64
  expect(sendBeaconMock).toHaveBeenCalledWith(
65
65
  `${baseUrl}/analytics/collect?visitorId=${currentVisitorId}&discardVisitInfo=true`,
66
- jasmine.anything()
66
+ expect.anything()
67
67
  );
68
68
  expect(await getSendBeaconFirstCallBlobArgument()).toBe(
69
69
  'access_token=%F0%9F%91%9B&pr1a=value&to%20encode=to%20encode'
@@ -92,7 +92,7 @@ describe('AnalyticsBeaconClient', () => {
92
92
 
93
93
  expect(sendBeaconMock).toHaveBeenCalledWith(
94
94
  `${baseUrl}/analytics/collect?visitorId=${currentVisitorId}&discardVisitInfo=true`,
95
- jasmine.anything()
95
+ expect.anything()
96
96
  );
97
97
  expect(await getSendBeaconFirstCallBlobArgument()).toBe(
98
98
  `access_token=%F0%9F%91%9B&value=${encodeURIComponent(JSON.stringify({subvalue: 'ok'}))}`
@@ -4,3 +4,14 @@ export const keysOf = Object.keys as <T>(o: T) => Extract<keyof T, string>[];
4
4
  export function isObject(o: any): boolean {
5
5
  return o !== null && typeof o === 'object' && !Array.isArray(o);
6
6
  }
7
+
8
+ /**
9
+ * Attempt to coerce strings to number values.
10
+ * Any non-number characters will fail parsing, in which case the input string is returned.
11
+ *
12
+ * @param input The input to possibly coerce to a number, if it is a string and parses to a number.
13
+ * @returns The input, possibly coerced to a number.
14
+ */
15
+ export function coerceToNumber(input: any): any {
16
+ return typeof input === 'string' && input != '' && !Number.isNaN(+input) ? +input : input;
17
+ }
@@ -16,4 +16,9 @@ export {
16
16
  export {CaseAssistClient, CaseAssistClientProvider} from '../caseAssist/caseAssistClient';
17
17
  export {CoveoInsightClient, InsightClientProvider} from '../insight/insightClient';
18
18
 
19
+ export * from '../searchPage/searchPageEvents';
20
+ export * from '../caseAssist/caseAssistActions';
21
+ export * from '../insight/insightEvents';
22
+ export * from '../events';
23
+
19
24
  export {analytics, donottrack, history, SimpleAnalytics, storage};
@@ -130,6 +130,9 @@ export class CoveoUA {
130
130
  }
131
131
 
132
132
  callPlugin(pluginName: string, fn: string, ...args: any): any {
133
+ if (!this.client) {
134
+ throw new Error(`You must call init before calling a plugin function`);
135
+ }
133
136
  return this.plugins.execute(pluginName, fn, ...args);
134
137
  }
135
138
 
@@ -1,4 +1,4 @@
1
- import {ECPlugin, ECPluginEventTypes} from './ec';
1
+ import {ECPlugin, ECPluginEventTypes, Product} from './ec';
2
2
  import {createAnalyticsClientMock} from '../../tests/analyticsClientMock';
3
3
 
4
4
  describe('EC plugin', () => {
@@ -119,6 +119,58 @@ describe('EC plugin', () => {
119
119
  expect(secondResult).toEqual({...defaultResult});
120
120
  });
121
121
 
122
+ it('should convert position to number if possible', () => {
123
+ const validValues = ['13', '5.5'];
124
+ for (const value of validValues) {
125
+ // @ts-ignore
126
+ ec.addProduct({name: 'product', position: value});
127
+
128
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
129
+ const expected: Record<string, any> = {...defaultResult, pr1nm: 'product', pr1ps: +value};
130
+
131
+ expect(result).toEqual(expected);
132
+ }
133
+ });
134
+
135
+ it('should keep original value if position is not a number', () => {
136
+ const invalidValues = ['1-2-3', '.', '-', '123abc'];
137
+ for (const value of invalidValues) {
138
+ // @ts-ignore
139
+ ec.addProduct({name: 'product', position: value});
140
+
141
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
142
+ const expected: Record<string, unknown> = {...defaultResult, pr1nm: 'product', pr1ps: value};
143
+
144
+ expect(result).toEqual(expected);
145
+ }
146
+ });
147
+
148
+ it('should convert quantity to number if possible', () => {
149
+ const validValues = ['13', '0', '.0', '-10', '5.0', '-1.1', '3.124e7'];
150
+ for (const value of validValues) {
151
+ // @ts-ignore
152
+ ec.addProduct({name: 'product', quantity: value});
153
+
154
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
155
+ const expected: Record<string, any> = {...defaultResult, pr1nm: 'product', pr1qt: +value};
156
+
157
+ expect(result).toEqual(expected);
158
+ }
159
+ });
160
+
161
+ it('should keep original value if quantity is not a number', () => {
162
+ const invalidValues = ['1-2-3', '', '.', '5..', '-', '123abc', 'abc123'];
163
+ for (const value of invalidValues) {
164
+ // @ts-ignore
165
+ ec.addProduct({name: 'product', quantity: value});
166
+
167
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
168
+ const expected: Record<string, unknown> = {...defaultResult, pr1nm: 'product', pr1qt: value};
169
+
170
+ expect(result).toEqual(expected);
171
+ }
172
+ });
173
+
122
174
  describe('when the position is invalid', () => {
123
175
  it('should warn when executing hook on added product', () => {
124
176
  jest.spyOn(console, 'warn').mockImplementation();
@@ -182,28 +234,23 @@ describe('EC plugin', () => {
182
234
  );
183
235
  });
184
236
 
185
- it('should tolerate an absent position', () => {
237
+ it('should tolerate an absent or undefined position', () => {
186
238
  jest.spyOn(console, 'warn').mockImplementation();
187
239
 
188
240
  ec.addProduct({
189
241
  name: 'A product with no position',
190
242
  });
191
243
 
192
- const undefinedPosition = undefined as any;
193
244
  ec.addProduct({
194
245
  name: 'A product with an undefined position',
195
- position: undefinedPosition,
246
+ position: undefined,
196
247
  });
197
248
 
198
249
  const result = executeRegisteredHook(ECPluginEventTypes.event, {});
199
250
 
200
251
  expect(console.warn).not.toHaveBeenCalled();
201
-
202
- const firstPositionProperty = 'il1pi1ps';
203
- expect(result).not.toHaveProperty(firstPositionProperty);
204
-
205
- const secondPositionProperty = 'il1pi2ps';
206
- expect(result).toHaveProperty(secondPositionProperty, undefinedPosition);
252
+ expect(result).not.toHaveProperty('pr1ps');
253
+ expect(result).toHaveProperty('pr2ps', undefined);
207
254
  });
208
255
  });
209
256
  });
@@ -401,28 +448,23 @@ describe('EC plugin', () => {
401
448
  );
402
449
  });
403
450
 
404
- it('should tolerate an absent position', () => {
451
+ it('should tolerate an absent or undefined position', () => {
405
452
  jest.spyOn(console, 'warn').mockImplementation();
406
453
 
407
454
  ec.addImpression({
408
455
  name: 'An impression with no position',
409
456
  });
410
457
 
411
- const undefinedPosition = undefined as any;
412
458
  ec.addImpression({
413
459
  name: 'An impression with an undefined position',
414
- position: undefinedPosition,
460
+ position: undefined,
415
461
  });
416
462
 
417
463
  const result = executeRegisteredHook(ECPluginEventTypes.event, {});
418
464
 
419
465
  expect(console.warn).not.toHaveBeenCalled();
420
-
421
- const firstPositionProperty = 'il1pi1ps';
422
- expect(result).not.toHaveProperty(firstPositionProperty);
423
-
424
- const secondPositionProperty = 'il1pi2ps';
425
- expect(result).toHaveProperty(secondPositionProperty, undefinedPosition);
466
+ expect(result).not.toHaveProperty('il1pi1ps');
467
+ expect(result).toHaveProperty('il1pi2ps', undefined);
426
468
  });
427
469
  });
428
470
  });
package/src/plugins/ec.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  convertImpressionListToMeasurementProtocol,
6
6
  } from '../client/measurementProtocolMapping/commerceMeasurementProtocolMapper';
7
7
  import {BasePlugin, BasePluginEventTypes, PluginClass, PluginOptions} from './BasePlugin';
8
+ import {coerceToNumber} from '../client/utils';
8
9
 
9
10
  export const ECPluginEventTypes = {
10
11
  ...BasePluginEventTypes,
@@ -160,11 +161,22 @@ export class ECPlugin extends BasePlugin {
160
161
  .reduce((newPayload, product, index) => {
161
162
  return {
162
163
  ...newPayload,
163
- ...convertProductToMeasurementProtocol(product, index),
164
+ ...convertProductToMeasurementProtocol(this.convertNumberTypes(product), index),
164
165
  };
165
166
  }, {});
166
167
  }
167
168
 
169
+ private convertNumberTypes(product: Product): Product {
170
+ let updatedProduct: Product = {...product};
171
+ if ('quantity' in updatedProduct) {
172
+ updatedProduct.quantity = coerceToNumber(updatedProduct.quantity);
173
+ }
174
+ if ('position' in updatedProduct) {
175
+ updatedProduct.position = coerceToNumber(updatedProduct.position);
176
+ }
177
+ return updatedProduct;
178
+ }
179
+
168
180
  private getImpressionPayload() {
169
181
  const impressionsByList = this.getImpressionsByList();
170
182
  return impressionsByList
@@ -17,13 +17,13 @@ describe('ReactNativeRuntime', () => {
17
17
  });
18
18
 
19
19
  it('should call "storage.getItem" when getting the visitor ID', async () => {
20
- spyOn(runtimeEnvironment.storage, 'getItem');
20
+ jest.spyOn(runtimeEnvironment.storage, 'getItem');
21
21
  await client.getCurrentVisitorId();
22
22
  expect(runtimeEnvironment.storage.getItem).toHaveBeenCalled();
23
23
  });
24
24
 
25
25
  it('should call "storage.getItem" when getting the visitor ID', async () => {
26
- spyOn(runtimeEnvironment.storage, 'setItem');
26
+ jest.spyOn(runtimeEnvironment.storage, 'setItem');
27
27
  await client.setCurrentVisitorId('myid');
28
28
  expect(runtimeEnvironment.storage.setItem).toHaveBeenCalled();
29
29
  });
@@ -1,66 +0,0 @@
1
- import { BasePlugin, PluginClass, PluginOptions } from './BasePlugin';
2
- export declare const ECPluginEventTypes: {
3
- pageview: string;
4
- event: string;
5
- };
6
- declare type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> & {
7
- [K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>;
8
- }[Keys];
9
- export declare type CustomValues = {
10
- [key: string]: string | number | boolean;
11
- };
12
- export interface CoveoExtensionProperties {
13
- group?: string;
14
- }
15
- export interface ProductProperties extends CoveoExtensionProperties {
16
- id?: string;
17
- name?: string;
18
- brand?: string;
19
- category?: string;
20
- variant?: string;
21
- price?: number;
22
- quantity?: number;
23
- coupon?: string;
24
- position?: number;
25
- custom?: CustomValues;
26
- }
27
- export declare type Product = RequireAtLeastOne<ProductProperties, 'id' | 'name'>;
28
- export interface ImpressionProperties extends CoveoExtensionProperties {
29
- id?: string;
30
- name?: string;
31
- list?: string;
32
- brand?: string;
33
- category?: string;
34
- variant?: string;
35
- position?: number;
36
- price?: number;
37
- custom?: CustomValues;
38
- }
39
- export declare type Impression = RequireAtLeastOne<ImpressionProperties, 'id' | 'name'>;
40
- export declare type BaseImpression = Omit<Impression, 'list'>;
41
- export interface ImpressionList {
42
- listName?: string;
43
- impressions: BaseImpression[];
44
- }
45
- export declare class ECPlugin extends BasePlugin {
46
- static readonly Id = "ec";
47
- private products;
48
- private impressions;
49
- constructor({ client, uuidGenerator }: PluginOptions);
50
- getApi(name: string): Function | null;
51
- protected addHooks(): void;
52
- addProduct(product: Product): void;
53
- addImpression(impression: Impression): void;
54
- protected clearPluginData(): void;
55
- private addHooksForECEvents;
56
- private addHooksForPageView;
57
- private addHooksForEvent;
58
- private addECDataToPayload;
59
- private getProductPayload;
60
- private getImpressionPayload;
61
- private assureProductValidity;
62
- private assureBaseImpressionValidity;
63
- private getImpressionsByList;
64
- }
65
- export declare const EC: PluginClass;
66
- export {};