coveo.analytics 2.30.56 → 2.32.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 (84) hide show
  1. package/README.md +37 -43
  2. package/dist/browser.mjs +513 -357
  3. package/dist/coveoua.browser.js +1 -1
  4. package/dist/coveoua.browser.js.map +1 -1
  5. package/dist/coveoua.debug.js +542 -359
  6. package/dist/coveoua.debug.js.map +1 -1
  7. package/dist/coveoua.js +1 -1
  8. package/dist/coveoua.js.map +1 -1
  9. package/dist/definitions/client/analytics.d.ts +3 -2
  10. package/dist/definitions/client/runtimeEnvironment.d.ts +1 -1
  11. package/dist/definitions/donottrack.d.ts +1 -0
  12. package/dist/definitions/react-native/index.d.ts +1 -2
  13. package/dist/definitions/version.d.ts +1 -1
  14. package/dist/library.cjs +15350 -3699
  15. package/dist/library.es.js +513 -357
  16. package/dist/library.js +15350 -3699
  17. package/dist/library.mjs +15350 -3699
  18. package/dist/react-native.es.js +634 -460
  19. package/modules/package.json +9 -9
  20. package/package.json +60 -91
  21. package/react-native/package.json +7 -7
  22. package/src/caseAssist/caseAssistActions.ts +51 -50
  23. package/src/caseAssist/caseAssistClient.spec.ts +328 -297
  24. package/src/caseAssist/caseAssistClient.ts +201 -185
  25. package/src/client/analytics.spec.ts +724 -703
  26. package/src/client/analytics.ts +677 -602
  27. package/src/client/analyticsBeaconClient.spec.ts +195 -188
  28. package/src/client/analyticsBeaconClient.ts +99 -88
  29. package/src/client/analyticsFetchClient.ts +77 -61
  30. package/src/client/analyticsRequestClient.ts +17 -17
  31. package/src/client/location.ts +3 -3
  32. package/src/client/measurementProtocolMapper.ts +54 -45
  33. package/src/client/measurementProtocolMapping/baseMeasurementProtocolMapper.ts +48 -44
  34. package/src/client/measurementProtocolMapping/commerceMeasurementProtocolMapper.ts +133 -121
  35. package/src/client/measurementProtocolMapping/serviceMeasurementProtocolMapper.ts +17 -17
  36. package/src/client/noopAnalytics.ts +80 -68
  37. package/src/client/runtimeEnvironment.ts +50 -41
  38. package/src/client/utils.spec.ts +112 -97
  39. package/src/client/utils.ts +39 -39
  40. package/src/cookieutils.spec.ts +59 -0
  41. package/src/cookieutils.ts +40 -39
  42. package/src/coveoua/browser.ts +14 -12
  43. package/src/coveoua/library.ts +4 -4
  44. package/src/coveoua/plugins.ts +36 -34
  45. package/src/coveoua/simpleanalytics.spec.ts +467 -452
  46. package/src/coveoua/simpleanalytics.ts +146 -140
  47. package/src/detector.ts +17 -17
  48. package/src/donottrack.spec.ts +199 -121
  49. package/src/donottrack.ts +31 -8
  50. package/src/events.ts +86 -79
  51. package/src/formatting/format-array-for-coveo-custom-data.spec.ts +13 -12
  52. package/src/formatting/format-array-for-coveo-custom-data.ts +18 -18
  53. package/src/formatting/format-omnibox-metadata.ts +16 -12
  54. package/src/history.spec.ts +197 -195
  55. package/src/history.ts +143 -133
  56. package/src/hook/addDefaultValues.ts +13 -8
  57. package/src/hook/enhanceViewEvent.ts +17 -17
  58. package/src/insight/insightClient.spec.ts +1848 -1717
  59. package/src/insight/insightClient.ts +866 -761
  60. package/src/insight/insightEvents.ts +57 -56
  61. package/src/plugins/BasePlugin.ts +125 -121
  62. package/src/plugins/ec.spec.ts +457 -429
  63. package/src/plugins/ec.ts +202 -199
  64. package/src/plugins/link.spec.ts +183 -159
  65. package/src/plugins/link.ts +88 -85
  66. package/src/plugins/svc.spec.ts +161 -155
  67. package/src/plugins/svc.ts +93 -91
  68. package/src/react-native/index.ts +8 -1
  69. package/src/react-native/react-native-runtime.ts +33 -33
  70. package/src/react-native/react-native-utils.ts +1 -1
  71. package/src/react-native/react-native.spec.ts +31 -21
  72. package/src/searchPage/searchPageClient.spec.ts +1944 -1794
  73. package/src/searchPage/searchPageClient.ts +1261 -1040
  74. package/src/searchPage/searchPageEvents.ts +524 -511
  75. package/src/storage.spec.ts +51 -51
  76. package/src/storage.ts +47 -47
  77. package/dist/definitions/bundle/browser-fetch.d.ts +0 -1
  78. package/dist/definitions/src/coveoua/browser.d.ts +0 -6
  79. package/dist/definitions/src/coveoua/headless.d.ts +0 -6
  80. package/dist/definitions/src/coveoua/library.d.ts +0 -17
  81. package/dist/definitions/src/coveoua/plugins.d.ts +0 -10
  82. package/dist/definitions/src/coveoua/simpleanalytics.d.ts +0 -33
  83. package/dist/definitions/src/react-native/index.d.ts +0 -3
  84. package/dist/definitions/src/react-native/react-native-runtime.d.ts +0 -19
@@ -1,171 +1,195 @@
1
+ import {vi} from 'vitest';
2
+ import type {Mock} from 'vitest';
1
3
  import {CoveoLinkParam, LinkPlugin} from './link';
2
4
  import {createAnalyticsClientMock} from '../../tests/analyticsClientMock';
3
5
  import {v4 as uuidv4} from 'uuid';
4
6
 
5
7
  function currentSecsSinceEpoch() {
6
- return Math.floor(Date.now() / 1000);
8
+ return Math.floor(Date.now() / 1000);
7
9
  }
8
10
 
9
11
  describe('CoveoLinkParam class', () => {
10
- it('can create a new link using a uuid', () => {
11
- const uuid = uuidv4();
12
- const link: CoveoLinkParam = new CoveoLinkParam(uuid, Date.now());
13
- expect(link.clientId).toBe(uuid);
14
- expect(link.creationDate).toBe(currentSecsSinceEpoch());
15
- });
16
-
17
- it('can create a new link using a uuid and timestamp', () => {
18
- const uuid = uuidv4();
19
- const link: CoveoLinkParam = new CoveoLinkParam(uuid, 1676298678329);
20
- expect(link.clientId).toBe(uuid);
21
- expect(link.creationDate).toBe(1676298678);
22
- });
23
-
24
- it('can not create a new link using a non uuid', () => {
25
- const uuid = 'Not_a_uuid';
26
- expect(() => new CoveoLinkParam(uuid, Date.now())).toThrow('Not a valid uuid');
27
- });
28
-
29
- it('can parse a link from a string', () => {
30
- const link = 'c0b48880743e484f8044d7c37910c55b.1676298678';
31
- const coveoLinkParam: CoveoLinkParam | null = CoveoLinkParam.fromString(link);
32
- expect(coveoLinkParam).not.toBeNull;
33
- expect(coveoLinkParam?.clientId).toBe('c0b48880-743e-484f-8044-d7c37910c55b');
34
- expect(coveoLinkParam?.creationDate).toBe(1676298678);
35
- });
36
-
37
- it('will not parse links without a valid uuid', () => {
38
- const link = 'a0c56830743d46537f703.1676298678';
39
- const coveoLinkParam: CoveoLinkParam | null = CoveoLinkParam.fromString(link);
40
- expect(coveoLinkParam).toBe(null);
41
- });
42
-
43
- it('will not parse links with an invalid structure', () => {
44
- const link = 'a0c56830743d46537f703.1676298678.353673463';
45
- const coveoLinkParam: CoveoLinkParam | null = CoveoLinkParam.fromString(link);
46
- expect(coveoLinkParam).toBe(null);
47
- });
48
-
49
- it('will not parse links with invalid timestamps', () => {
50
- const link = 'a0c56830743d46537f703.invalidtimestamp';
51
- const coveoLinkParam: CoveoLinkParam | null = CoveoLinkParam.fromString(link);
52
- expect(coveoLinkParam).toBe(null);
53
- });
54
-
55
- it('can serialize a link to a string', () => {
56
- const coveoLink: CoveoLinkParam = new CoveoLinkParam('074af291-224b-4705-9dc5-a47bd80a8db9', Date.now());
57
- const link = coveoLink.toString();
58
- const parts = link.split('.');
59
- expect(parts[0]).toBe('074af291224b47059dc5a47bd80a8db9');
60
- expect(Number.parseInt(parts[1])).toBe(currentSecsSinceEpoch());
61
- });
62
-
63
- it('checks for expiration on a link', () => {
64
- const coveoLink1: CoveoLinkParam = new CoveoLinkParam('074af291-224b-4705-9dc5-a47bd80a8db9', Date.now());
65
- expect(coveoLink1.expired).toBe(false);
66
- const coveoLink2: CoveoLinkParam = new CoveoLinkParam(
67
- '074af291-224b-4705-9dc5-a47bd80a8db9',
68
- Date.now() - 180000,
69
- );
70
- expect(coveoLink2.expired).toBe(true);
71
- });
72
-
73
- it('checks for expiration on a link if the timestamp is in the future', () => {
74
- const coveoLink1: CoveoLinkParam = new CoveoLinkParam('074af291-224b-4705-9dc5-a47bd80a8db9', Date.now());
75
- expect(coveoLink1.expired).toBe(false);
76
- const coveoLink2: CoveoLinkParam = new CoveoLinkParam(
77
- '074af291-224b-4705-9dc5-a47bd80a8db9',
78
- Date.now() + 5000,
79
- );
80
- expect(coveoLink2.expired).toBe(true);
81
- });
82
-
83
- it('checks validation on referrers', () => {
84
- const coveoLink1: CoveoLinkParam = new CoveoLinkParam('074af291-224b-4705-9dc5-a47bd80a8db9', Date.now());
85
- expect(coveoLink1.validate('http://sub.mysite.com', ['*'])).toBe(true);
86
- expect(coveoLink1.validate('http://sub.mysite.com', ['*.mysite.com', '*'])).toBe(true);
87
- expect(coveoLink1.validate('http://sub.mysite.com', ['*.mysite.com'])).toBe(true);
88
- expect(coveoLink1.validate('http://sub.notmysite.com', ['*.mysite.com'])).toBe(false);
89
- expect(coveoLink1.validate('http://sub.mysite.com', [])).toBe(false);
90
- });
91
-
92
- it('escapes backslash correctly', () => {
93
- const coveoLink1: CoveoLinkParam = new CoveoLinkParam('074af291-224b-4705-9dc5-a47bd80a8db9', Date.now());
94
- expect(coveoLink1.validate('http://sub.mysite.com', ['\\w'])).toBe(false); // This should not be treated as a \w regexp!
95
- });
12
+ it('can create a new link using a uuid', () => {
13
+ const uuid = uuidv4();
14
+ const link: CoveoLinkParam = new CoveoLinkParam(uuid, Date.now());
15
+ expect(link.clientId).toBe(uuid);
16
+ expect(link.creationDate).toBe(currentSecsSinceEpoch());
17
+ });
18
+
19
+ it('can create a new link using a uuid and timestamp', () => {
20
+ const uuid = uuidv4();
21
+ const link: CoveoLinkParam = new CoveoLinkParam(uuid, 1676298678329);
22
+ expect(link.clientId).toBe(uuid);
23
+ expect(link.creationDate).toBe(1676298678);
24
+ });
25
+
26
+ it('can not create a new link using a non uuid', () => {
27
+ const uuid = 'Not_a_uuid';
28
+ expect(() => new CoveoLinkParam(uuid, Date.now())).toThrow('Not a valid uuid');
29
+ });
30
+
31
+ it('can parse a link from a string', () => {
32
+ const link = 'c0b48880743e484f8044d7c37910c55b.1676298678';
33
+ const coveoLinkParam: CoveoLinkParam | null = CoveoLinkParam.fromString(link);
34
+ expect(coveoLinkParam).not.toBeNull;
35
+ expect(coveoLinkParam?.clientId).toBe('c0b48880-743e-484f-8044-d7c37910c55b');
36
+ expect(coveoLinkParam?.creationDate).toBe(1676298678);
37
+ });
38
+
39
+ it('will not parse links without a valid uuid', () => {
40
+ const link = 'a0c56830743d46537f703.1676298678';
41
+ const coveoLinkParam: CoveoLinkParam | null = CoveoLinkParam.fromString(link);
42
+ expect(coveoLinkParam).toBe(null);
43
+ });
44
+
45
+ it('will not parse links with an invalid structure', () => {
46
+ const link = 'a0c56830743d46537f703.1676298678.353673463';
47
+ const coveoLinkParam: CoveoLinkParam | null = CoveoLinkParam.fromString(link);
48
+ expect(coveoLinkParam).toBe(null);
49
+ });
50
+
51
+ it('will not parse links with invalid timestamps', () => {
52
+ const link = 'a0c56830743d46537f703.invalidtimestamp';
53
+ const coveoLinkParam: CoveoLinkParam | null = CoveoLinkParam.fromString(link);
54
+ expect(coveoLinkParam).toBe(null);
55
+ });
56
+
57
+ it('can serialize a link to a string', () => {
58
+ const coveoLink: CoveoLinkParam = new CoveoLinkParam(
59
+ '074af291-224b-4705-9dc5-a47bd80a8db9',
60
+ Date.now()
61
+ );
62
+ const link = coveoLink.toString();
63
+ const parts = link.split('.');
64
+ expect(parts[0]).toBe('074af291224b47059dc5a47bd80a8db9');
65
+ expect(Number.parseInt(parts[1])).toBe(currentSecsSinceEpoch());
66
+ });
67
+
68
+ it('checks for expiration on a link', () => {
69
+ const coveoLink1: CoveoLinkParam = new CoveoLinkParam(
70
+ '074af291-224b-4705-9dc5-a47bd80a8db9',
71
+ Date.now()
72
+ );
73
+ expect(coveoLink1.expired).toBe(false);
74
+ const coveoLink2: CoveoLinkParam = new CoveoLinkParam(
75
+ '074af291-224b-4705-9dc5-a47bd80a8db9',
76
+ Date.now() - 180000
77
+ );
78
+ expect(coveoLink2.expired).toBe(true);
79
+ });
80
+
81
+ it('checks for expiration on a link if the timestamp is in the future', () => {
82
+ const coveoLink1: CoveoLinkParam = new CoveoLinkParam(
83
+ '074af291-224b-4705-9dc5-a47bd80a8db9',
84
+ Date.now()
85
+ );
86
+ expect(coveoLink1.expired).toBe(false);
87
+ const coveoLink2: CoveoLinkParam = new CoveoLinkParam(
88
+ '074af291-224b-4705-9dc5-a47bd80a8db9',
89
+ Date.now() + 5000
90
+ );
91
+ expect(coveoLink2.expired).toBe(true);
92
+ });
93
+
94
+ it('checks validation on referrers', () => {
95
+ const coveoLink1: CoveoLinkParam = new CoveoLinkParam(
96
+ '074af291-224b-4705-9dc5-a47bd80a8db9',
97
+ Date.now()
98
+ );
99
+ expect(coveoLink1.validate('http://sub.mysite.com', ['*'])).toBe(true);
100
+ expect(coveoLink1.validate('http://sub.mysite.com', ['*.mysite.com', '*'])).toBe(true);
101
+ expect(coveoLink1.validate('http://sub.mysite.com', ['*.mysite.com'])).toBe(true);
102
+ expect(coveoLink1.validate('http://sub.notmysite.com', ['*.mysite.com'])).toBe(false);
103
+ expect(coveoLink1.validate('http://sub.mysite.com', [])).toBe(false);
104
+ });
105
+
106
+ it('escapes backslash correctly', () => {
107
+ const coveoLink1: CoveoLinkParam = new CoveoLinkParam(
108
+ '074af291-224b-4705-9dc5-a47bd80a8db9',
109
+ Date.now()
110
+ );
111
+ expect(coveoLink1.validate('http://sub.mysite.com', ['\\w'])).toBe(false); // This should not be treated as a \w regexp!
112
+ });
96
113
  });
97
114
 
98
115
  describe('CoveoLinkPlugin', () => {
99
- let link: LinkPlugin;
100
-
101
- beforeEach(() => {
102
- jest.clearAllMocks();
103
- const analyticsClient = createAnalyticsClientMock();
104
- analyticsClient.getCurrentVisitorId = jest.fn(() => Promise.resolve('85698661-efdf-4c6d-9cad-c4632bf81ce3'));
105
- link = new LinkPlugin({client: analyticsClient});
106
- });
107
-
108
- it('decorates links with valid urls and no params', async () => {
109
- const url: string = 'https://coveo.com';
110
- const result: string = await link.decorate(url);
111
- expect(result).toBe('https://coveo.com/?cvo_cid=85698661efdf4c6d9cadc4632bf81ce3.' + currentSecsSinceEpoch());
112
- });
113
-
114
- it('decorates links with valid urls and no params', async () => {
115
- const url: string = 'https://coveo.com/some/path/';
116
- const result: string = await link.decorate(url);
117
- expect(result).toBe(
118
- 'https://coveo.com/some/path/?cvo_cid=85698661efdf4c6d9cadc4632bf81ce3.' + currentSecsSinceEpoch(),
119
- );
120
- });
121
-
122
- it('decorates links with valid urls and existing params', async () => {
123
- const url: string = 'https://coveo.com/query?q=something&p=param';
124
- const result: string = await link.decorate(url);
125
- expect(result).toBe(
126
- 'https://coveo.com/query?q=something&p=param&cvo_cid=85698661efdf4c6d9cadc4632bf81ce3.' +
127
- currentSecsSinceEpoch(),
128
- );
129
- });
130
-
131
- it('decorates links with valid urls, existing params and fragments', async () => {
132
- const url: string = 'https://coveo.com/?q=something#frag';
133
- const result: string = await link.decorate(url);
134
- expect(result).toBe(
135
- 'https://coveo.com/?q=something&cvo_cid=85698661efdf4c6d9cadc4632bf81ce3.' +
136
- currentSecsSinceEpoch() +
137
- '#frag',
138
- );
139
- });
140
-
141
- it('updates an existing decoration links with valid urls and no params', async () => {
142
- const url: string = 'https://coveo.com/?cvo_cid=c0b48880743e484f8044d7c37910c55b.1676298678';
143
- const result: string = await link.decorate(url);
144
- expect(result).toBe('https://coveo.com/?cvo_cid=85698661efdf4c6d9cadc4632bf81ce3.' + currentSecsSinceEpoch());
145
- });
146
-
147
- it('errors on invalid urls', async () => {
148
- const url: string = 'somethingthatisobviouslynotaurl';
149
- await expect(link.decorate(url)).rejects.toThrow('Invalid URL provided');
150
- });
151
-
152
- it('errors when there is no current clientId', async () => {
153
- // initialize with missing clientId method
154
- const analyticsClient = createAnalyticsClientMock();
155
- analyticsClient.getCurrentVisitorId = undefined;
156
- link = new LinkPlugin({client: analyticsClient});
157
-
158
- const url: string = 'https://coveo.com/';
159
- await expect(link.decorate(url)).rejects.toThrow('Could not retrieve current clientId');
160
- });
161
-
162
- it('can set a list of referrers on the client', () => {
163
- const analyticsClient = createAnalyticsClientMock();
164
- const mock: jest.Mock = jest.fn();
165
- analyticsClient.setAcceptedLinkReferrers = mock;
166
- link = new LinkPlugin({client: analyticsClient});
167
- link.acceptFrom(['*.somedomain.com', 'www.coveo.com']);
168
-
169
- expect(mock).toHaveBeenCalledTimes(1);
170
- });
116
+ let link: LinkPlugin;
117
+
118
+ beforeEach(() => {
119
+ vi.clearAllMocks();
120
+ const analyticsClient = createAnalyticsClientMock();
121
+ analyticsClient.getCurrentVisitorId = vi.fn(() =>
122
+ Promise.resolve('85698661-efdf-4c6d-9cad-c4632bf81ce3')
123
+ );
124
+ link = new LinkPlugin({client: analyticsClient});
125
+ });
126
+
127
+ it('decorates links with valid urls and no params', async () => {
128
+ const url: string = 'https://coveo.com';
129
+ const result: string = await link.decorate(url);
130
+ expect(result).toBe(
131
+ 'https://coveo.com/?cvo_cid=85698661efdf4c6d9cadc4632bf81ce3.' + currentSecsSinceEpoch()
132
+ );
133
+ });
134
+
135
+ it('decorates links with valid urls and no params', async () => {
136
+ const url: string = 'https://coveo.com/some/path/';
137
+ const result: string = await link.decorate(url);
138
+ expect(result).toBe(
139
+ 'https://coveo.com/some/path/?cvo_cid=85698661efdf4c6d9cadc4632bf81ce3.' +
140
+ currentSecsSinceEpoch()
141
+ );
142
+ });
143
+
144
+ it('decorates links with valid urls and existing params', async () => {
145
+ const url: string = 'https://coveo.com/query?q=something&p=param';
146
+ const result: string = await link.decorate(url);
147
+ expect(result).toBe(
148
+ 'https://coveo.com/query?q=something&p=param&cvo_cid=85698661efdf4c6d9cadc4632bf81ce3.' +
149
+ currentSecsSinceEpoch()
150
+ );
151
+ });
152
+
153
+ it('decorates links with valid urls, existing params and fragments', async () => {
154
+ const url: string = 'https://coveo.com/?q=something#frag';
155
+ const result: string = await link.decorate(url);
156
+ expect(result).toBe(
157
+ 'https://coveo.com/?q=something&cvo_cid=85698661efdf4c6d9cadc4632bf81ce3.' +
158
+ currentSecsSinceEpoch() +
159
+ '#frag'
160
+ );
161
+ });
162
+
163
+ it('updates an existing decoration links with valid urls and no params', async () => {
164
+ const url: string = 'https://coveo.com/?cvo_cid=c0b48880743e484f8044d7c37910c55b.1676298678';
165
+ const result: string = await link.decorate(url);
166
+ expect(result).toBe(
167
+ 'https://coveo.com/?cvo_cid=85698661efdf4c6d9cadc4632bf81ce3.' + currentSecsSinceEpoch()
168
+ );
169
+ });
170
+
171
+ it('errors on invalid urls', async () => {
172
+ const url: string = 'invalidTestUrl';
173
+ await expect(link.decorate(url)).rejects.toThrow('Invalid URL provided');
174
+ });
175
+
176
+ it('errors when there is no current clientId', async () => {
177
+ // initialize with missing clientId method
178
+ const analyticsClient = createAnalyticsClientMock();
179
+ analyticsClient.getCurrentVisitorId = undefined;
180
+ link = new LinkPlugin({client: analyticsClient});
181
+
182
+ const url: string = 'https://coveo.com/';
183
+ await expect(link.decorate(url)).rejects.toThrow('Could not retrieve current clientId');
184
+ });
185
+
186
+ it('can set a list of referrers on the client', () => {
187
+ const analyticsClient = createAnalyticsClientMock();
188
+ const mock: Mock = vi.fn();
189
+ analyticsClient.setAcceptedLinkReferrers = mock;
190
+ link = new LinkPlugin({client: analyticsClient});
191
+ link.acceptFrom(['*.somedomain.com', 'www.coveo.com']);
192
+
193
+ expect(mock).toHaveBeenCalledTimes(1);
194
+ });
171
195
  });
@@ -2,108 +2,111 @@ import {validate as uuidvalidate, v4 as uuidv4} from 'uuid';
2
2
  import {Plugin, PluginOptions, PluginClass} from './BasePlugin';
3
3
 
4
4
  export class CoveoLinkParam {
5
- public static readonly cvo_cid: string = 'cvo_cid'; // name of the url parameter
6
- private static readonly expirationTime: number = 120; // expirationTime in secs
7
- public readonly clientId: string; //uuid
8
- public readonly creationDate: number; //seconds since epoch to save space in serialized param
5
+ public static readonly cvo_cid: string = 'cvo_cid'; // name of the url parameter
6
+ private static readonly expirationTime: number = 120; // expirationTime in secs
7
+ public readonly clientId: string; //uuid
8
+ public readonly creationDate: number; //seconds since epoch to save space in serialized param
9
9
 
10
- constructor(clientId: string, timestamp: number) {
11
- if (!uuidvalidate(clientId)) throw Error('Not a valid uuid');
12
- this.clientId = clientId;
13
- this.creationDate = Math.floor(timestamp / 1000);
14
- }
10
+ constructor(clientId: string, timestamp: number) {
11
+ if (!uuidvalidate(clientId)) throw Error('Not a valid uuid');
12
+ this.clientId = clientId;
13
+ this.creationDate = Math.floor(timestamp / 1000);
14
+ }
15
15
 
16
- public toString(): string {
17
- // strips the dashes and uses second granularity to save on url length.
18
- return this.clientId.replace(/-/g, '') + '.' + this.creationDate.toString();
19
- }
16
+ public toString(): string {
17
+ // strips the dashes and uses second granularity to save on url length.
18
+ return this.clientId.replace(/-/g, '') + '.' + this.creationDate.toString();
19
+ }
20
20
 
21
- public get expired(): boolean {
22
- const age = Math.floor(Date.now() / 1000) - this.creationDate;
23
- return age < 0 || age > CoveoLinkParam.expirationTime;
24
- }
21
+ public get expired(): boolean {
22
+ const age = Math.floor(Date.now() / 1000) - this.creationDate;
23
+ return age < 0 || age > CoveoLinkParam.expirationTime;
24
+ }
25
25
 
26
- public validate(referrerString: string, referrerList: string[]): boolean {
27
- return !this.expired && this.matchReferrer(referrerString, referrerList);
28
- }
26
+ public validate(referrerString: string, referrerList: string[]): boolean {
27
+ return !this.expired && this.matchReferrer(referrerString, referrerList);
28
+ }
29
29
 
30
- private matchReferrer(referrerString: string, referrerList: string[]): boolean {
31
- try {
32
- const url: URL = new URL(referrerString);
33
- return referrerList.some((value: string) => {
34
- const hostRegExp: RegExp = new RegExp(
35
- value.replace(/\\/g, '\\\\').replace(/\./g, '\\.').replace(/\*/g, '.*') + '$',
36
- );
37
- return hostRegExp.test(url.host);
38
- });
39
- } catch (error) {
40
- return false;
41
- }
30
+ private matchReferrer(referrerString: string, referrerList: string[]): boolean {
31
+ try {
32
+ const url: URL = new URL(referrerString);
33
+ return referrerList.some((value: string) => {
34
+ const hostRegExp: RegExp = new RegExp(
35
+ value.replace(/\\/g, '\\\\').replace(/\./g, '\\.').replace(/\*/g, '.*') + '$'
36
+ );
37
+ return hostRegExp.test(url.host);
38
+ });
39
+ } catch (error) {
40
+ return false;
42
41
  }
42
+ }
43
43
 
44
- public static fromString(input: string): CoveoLinkParam | null {
45
- const parts = input.split('.');
46
- if (parts.length !== 2) {
47
- return null;
48
- }
49
- const [clientIdPart, creationDate] = parts;
50
- if (clientIdPart.length !== 32 || isNaN(parseInt(creationDate))) {
51
- return null;
52
- }
53
- const clientId =
54
- clientIdPart.substring(0, 8) +
55
- '-' +
56
- clientIdPart.substring(8, 12) +
57
- '-' +
58
- clientIdPart.substring(12, 16) +
59
- '-' +
60
- clientIdPart.substring(16, 20) +
61
- '-' +
62
- clientIdPart.substring(20, 32);
63
- if (uuidvalidate(clientId)) {
64
- return new CoveoLinkParam(clientId, Number.parseInt(creationDate) * 1000);
65
- } else {
66
- return null;
67
- }
44
+ public static fromString(input: string): CoveoLinkParam | null {
45
+ const parts = input.split('.');
46
+ if (parts.length !== 2) {
47
+ return null;
48
+ }
49
+ const [clientIdPart, creationDate] = parts;
50
+ if (clientIdPart.length !== 32 || isNaN(parseInt(creationDate))) {
51
+ return null;
68
52
  }
53
+ const clientId =
54
+ clientIdPart.substring(0, 8) +
55
+ '-' +
56
+ clientIdPart.substring(8, 12) +
57
+ '-' +
58
+ clientIdPart.substring(12, 16) +
59
+ '-' +
60
+ clientIdPart.substring(16, 20) +
61
+ '-' +
62
+ clientIdPart.substring(20, 32);
63
+ if (uuidvalidate(clientId)) {
64
+ return new CoveoLinkParam(clientId, Number.parseInt(creationDate) * 1000);
65
+ } else {
66
+ return null;
67
+ }
68
+ }
69
69
  }
70
70
 
71
71
  export class LinkPlugin extends Plugin {
72
- public static readonly Id = 'link';
72
+ public static readonly Id = 'link';
73
73
 
74
- constructor({client, uuidGenerator = uuidv4}: PluginOptions) {
75
- super({client, uuidGenerator});
76
- }
74
+ constructor({client, uuidGenerator = uuidv4}: PluginOptions) {
75
+ super({client, uuidGenerator});
76
+ }
77
77
 
78
- public getApi(name: string): Function | null {
79
- switch (name) {
80
- case 'decorate':
81
- return this.decorate;
82
- case 'acceptFrom':
83
- return this.acceptFrom;
84
- default:
85
- return null;
86
- }
78
+ public getApi(name: string): Function | null {
79
+ switch (name) {
80
+ case 'decorate':
81
+ return this.decorate;
82
+ case 'acceptFrom':
83
+ return this.acceptFrom;
84
+ default:
85
+ return null;
87
86
  }
87
+ }
88
88
 
89
- public async decorate(urlString: string): Promise<string> {
90
- // Note: clientId retrieval function is marked as optional
91
- if (!this.client.getCurrentVisitorId) {
92
- throw new Error('Could not retrieve current clientId');
93
- }
94
- try {
95
- const url = new URL(urlString);
96
- const clientId: string = await this.client.getCurrentVisitorId!();
97
- url.searchParams.set(CoveoLinkParam.cvo_cid, new CoveoLinkParam(clientId, Date.now()).toString());
98
- return url.toString();
99
- } catch (error) {
100
- throw new Error('Invalid URL provided');
101
- }
89
+ public async decorate(urlString: string): Promise<string> {
90
+ // Note: clientId retrieval function is marked as optional
91
+ if (!this.client.getCurrentVisitorId) {
92
+ throw new Error('Could not retrieve current clientId');
102
93
  }
103
-
104
- public acceptFrom(acceptedReferrers: string[]) {
105
- this.client.setAcceptedLinkReferrers!(acceptedReferrers);
94
+ try {
95
+ const url = new URL(urlString);
96
+ const clientId: string = await this.client.getCurrentVisitorId!();
97
+ url.searchParams.set(
98
+ CoveoLinkParam.cvo_cid,
99
+ new CoveoLinkParam(clientId, Date.now()).toString()
100
+ );
101
+ return url.toString();
102
+ } catch (error) {
103
+ throw new Error('Invalid URL provided');
106
104
  }
105
+ }
106
+
107
+ public acceptFrom(acceptedReferrers: string[]) {
108
+ this.client.setAcceptedLinkReferrers!(acceptedReferrers);
109
+ }
107
110
  }
108
111
 
109
112
  export const Link: PluginClass = LinkPlugin;