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.
- package/README.md +37 -43
- package/dist/browser.mjs +513 -357
- package/dist/coveoua.browser.js +1 -1
- package/dist/coveoua.browser.js.map +1 -1
- package/dist/coveoua.debug.js +542 -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 -2
- package/dist/definitions/version.d.ts +1 -1
- package/dist/library.cjs +15350 -3699
- package/dist/library.es.js +513 -357
- package/dist/library.js +15350 -3699
- package/dist/library.mjs +15350 -3699
- package/dist/react-native.es.js +634 -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 +8 -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 +31 -21
- package/src/searchPage/searchPageClient.spec.ts +1944 -1794
- package/src/searchPage/searchPageClient.ts +1261 -1040
- package/src/searchPage/searchPageEvents.ts +524 -511
- 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/link.spec.ts
CHANGED
|
@@ -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
|
-
|
|
8
|
+
return Math.floor(Date.now() / 1000);
|
|
7
9
|
}
|
|
8
10
|
|
|
9
11
|
describe('CoveoLinkParam class', () => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
});
|
package/src/plugins/link.ts
CHANGED
|
@@ -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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
public validate(referrerString: string, referrerList: string[]): boolean {
|
|
27
|
+
return !this.expired && this.matchReferrer(referrerString, referrerList);
|
|
28
|
+
}
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
72
|
+
public static readonly Id = 'link';
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
constructor({client, uuidGenerator = uuidv4}: PluginOptions) {
|
|
75
|
+
super({client, uuidGenerator});
|
|
76
|
+
}
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
|
|
105
|
-
|
|
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;
|