coveo.analytics 2.23.10 → 2.25.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 (38) 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 +330 -56
  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/client/analytics.d.ts +3 -0
  8. package/dist/definitions/client/noopAnalytics.d.ts +1 -0
  9. package/dist/definitions/cookieutils.d.ts +1 -1
  10. package/dist/definitions/coveoua/simpleanalytics.d.ts +1 -0
  11. package/dist/definitions/plugins/BasePlugin.d.ts +1 -1
  12. package/dist/definitions/src/coveoua/simpleanalytics.d.ts +1 -0
  13. package/dist/definitions/storage.d.ts +1 -1
  14. package/dist/definitions/version.d.ts +1 -0
  15. package/dist/library.es.js +309 -53
  16. package/dist/library.js +324 -53
  17. package/dist/react-native.es.js +81819 -59
  18. package/package.json +5 -2
  19. package/src/client/analytics.spec.ts +42 -12
  20. package/src/client/analytics.ts +22 -1
  21. package/src/client/analyticsBeaconClient.spec.ts +1 -1
  22. package/src/client/noopAnalytics.ts +4 -0
  23. package/src/cookieutils.ts +21 -42
  24. package/src/coveoua/browser.ts +2 -2
  25. package/src/coveoua/plugins.ts +1 -1
  26. package/src/coveoua/simpleanalytics.spec.ts +11 -5
  27. package/src/coveoua/simpleanalytics.ts +6 -0
  28. package/src/plugins/BasePlugin.ts +3 -4
  29. package/src/plugins/ec.spec.ts +1 -1
  30. package/src/plugins/ec.ts +1 -1
  31. package/src/plugins/svc.spec.ts +1 -1
  32. package/src/plugins/svc.ts +1 -1
  33. package/src/react-native/react-native-runtime.ts +1 -1
  34. package/src/storage.spec.ts +8 -0
  35. package/src/storage.ts +3 -3
  36. package/src/version.ts +1 -0
  37. package/dist/definitions/client/crypto.d.ts +0 -1
  38. package/src/client/crypto.ts +0 -21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coveo.analytics",
3
- "version": "2.23.10",
3
+ "version": "2.25.1",
4
4
  "description": "📈 Coveo analytics client (node and browser compatible) ",
5
5
  "main": "dist/library.js",
6
6
  "module": "dist/library.es.js",
@@ -23,18 +23,21 @@
23
23
  },
24
24
  "license": "MIT",
25
25
  "dependencies": {
26
- "cross-fetch": "^3.1.5"
26
+ "cross-fetch": "^3.1.5",
27
+ "uuid": "^9.0.0"
27
28
  },
28
29
  "devDependencies": {
29
30
  "@rollup/plugin-alias": "^3.1.2",
30
31
  "@rollup/plugin-commonjs": "^19.0.0",
31
32
  "@rollup/plugin-json": "^4.1.0",
32
33
  "@rollup/plugin-node-resolve": "^13.0.0",
34
+ "@rollup/plugin-replace": "^5.0.2",
33
35
  "@types/fetch-mock": "^7.3.2",
34
36
  "@types/jest": "^25.1.1",
35
37
  "@types/jsdom": "^12.2.4",
36
38
  "@types/mime": "0.0.29",
37
39
  "@types/node": "^6.0.45",
40
+ "@types/uuid": "^9.0.0",
38
41
  "babel-core": "^6.17.0",
39
42
  "babel-loader": "^7.1.4",
40
43
  "babel-preset-es2015": "^6.16.0",
@@ -9,10 +9,10 @@ import * as doNotTrack from '../donottrack';
9
9
  import {Cookie} from '../cookieutils';
10
10
 
11
11
  const aVisitorId = '123';
12
-
13
- const uuidv4Mock = jest.fn();
14
- jest.mock('./crypto', () => ({
15
- uuidv4: () => uuidv4Mock(),
12
+ jest.mock('uuid', () => ({
13
+ v4: () => aVisitorId,
14
+ validate: jest.requireActual('uuid').validate,
15
+ v5: jest.requireActual('uuid').v5,
16
16
  }));
17
17
 
18
18
  const {fetchMock, fetchMockBeforeEach} = mockFetch();
@@ -49,7 +49,6 @@ describe('Analytics', () => {
49
49
  new CookieStorage().removeItem('visitorId');
50
50
  localStorage.clear();
51
51
  fetchMock.reset();
52
- uuidv4Mock.mockImplementationOnce(() => aVisitorId);
53
52
 
54
53
  client = new CoveoAnalyticsClient({
55
54
  token: aToken,
@@ -66,7 +65,7 @@ describe('Analytics', () => {
66
65
 
67
66
  expect(fetchMock.called()).toBe(true);
68
67
 
69
- const [path, {headers, body}] = fetchMock.lastCall();
68
+ const [path, {headers, body}]: any = fetchMock.lastCall();
70
69
  expect(path).toBe(endpointForEventType(EventType.view));
71
70
 
72
71
  const h = headers as Record<string, string>;
@@ -115,8 +114,8 @@ describe('Analytics', () => {
115
114
 
116
115
  await Promise.all([firstRequest, secondRequest, thirdRequest]);
117
116
 
118
- const assertResponseHasCustomDataWithIndex = (response: RequestInit, index: number) => {
119
- const parsedBody = JSON.parse(response.body.toString());
117
+ const assertResponseHasCustomDataWithIndex = (response: RequestInit | undefined, index: number) => {
118
+ const parsedBody = JSON.parse(response!.body!.toString());
120
119
  expect(parsedBody.customData.index).toBe(index);
121
120
  };
122
121
  const [[, firstResponse], [, secondResponse], [, thirdResponse]] = fetchMock.calls();
@@ -170,7 +169,7 @@ describe('Analytics', () => {
170
169
  it('should properly parse empty arguments', async () => {
171
170
  await client.sendEvent(specialEventType);
172
171
 
173
- const [path, {body}] = fetchMock.lastCall();
172
+ const [path, {body}]: any = fetchMock.lastCall();
174
173
  expect(path).toBe(endpointForEventType(EventType.custom));
175
174
 
176
175
  const parsedBody = JSON.parse(body.toString());
@@ -409,16 +408,16 @@ describe('Analytics', () => {
409
408
 
410
409
  const call = fetchMock.calls()[0];
411
410
  const url = call[0];
412
- const options: RequestInit = call[1];
411
+ const options: RequestInit | undefined = call[1];
413
412
 
414
413
  const {url: expectedUrl, ...expectedOptions} = processedRequest;
415
- expect(clientOrigin).toBe('analyticsFetch');
414
+ expect(clientOrigin!).toBe('analyticsFetch');
416
415
  expect(url).toBe(expectedUrl);
417
416
  expect(options).toEqual(expectedOptions);
418
417
  });
419
418
 
420
419
  const getParsedBodyCalls = (): any[] => {
421
- return fetchMock.calls().map(([, {body}]) => {
420
+ return fetchMock.calls().map(([, {body}]: any) => {
422
421
  return JSON.parse(body.toString());
423
422
  });
424
423
  };
@@ -453,3 +452,34 @@ describe('doNotTrack', () => {
453
452
  expect(Cookie.get('coveo_visitorId')).not.toBe(aVisitorId);
454
453
  });
455
454
  });
455
+
456
+ describe('custom clientId', () => {
457
+ it('allows setting of a custom clientId', async () => {
458
+ const client = new CoveoAnalyticsClient({});
459
+ client.setClientId('c7d57b22-4aa8-487a-a106-be5243885f0a');
460
+ expect(await client.getCurrentVisitorId()).toBe('c7d57b22-4aa8-487a-a106-be5243885f0a');
461
+ });
462
+
463
+ it('allows setting a custom consistent clientId given a string', async () => {
464
+ const client = new CoveoAnalyticsClient({});
465
+ client.setClientId('somestring', 'testNameSpace');
466
+ //uuid v5 specific uuid generation
467
+ expect(await client.getCurrentVisitorId()).toBe('2c356915-8223-5773-acb8-e2a34404a559');
468
+ //check for consistent ids
469
+ client.setClientId('somestring', 'testNameSpace');
470
+ expect(await client.getCurrentVisitorId()).toBe('2c356915-8223-5773-acb8-e2a34404a559');
471
+ client.setClientId('otherstring', 'testNameSpace');
472
+ expect(await client.getCurrentVisitorId()).not.toBe('2c356915-8223-5773-acb8-e2a34404a559');
473
+ client.setClientId('somestring', 'otherNameSpace');
474
+ expect(await client.getCurrentVisitorId()).not.toBe('2c356915-8223-5773-acb8-e2a34404a559');
475
+ });
476
+
477
+ it('errors when not providing a namespace', async () => {
478
+ const client = new CoveoAnalyticsClient({});
479
+ expect.assertions(1);
480
+ await expect(client.setClientId('somestring')).rejects.toEqual(
481
+ Error('Cannot generate uuid client id without a specific namespace string.')
482
+ );
483
+ //uuid v5 specific uuid generation
484
+ });
485
+ });
@@ -22,7 +22,8 @@ import {IAnalyticsClientOptions, PreprocessAnalyticsRequest, VisitorIdProvider}
22
22
  import {hasWindow, hasDocument} from '../detector';
23
23
  import {addDefaultValues} from '../hook/addDefaultValues';
24
24
  import {enhanceViewEvent} from '../hook/enhanceViewEvent';
25
- import {uuidv4} from './crypto';
25
+ import {v4 as uuidv4, v5 as uuidv5, validate as uuidValidate} from 'uuid';
26
+ import {libVersion} from '../version';
26
27
  import {
27
28
  convertKeysToMeasurementProtocol,
28
29
  isMeasurementProtocolKey,
@@ -98,6 +99,7 @@ export interface AnalyticsClient {
98
99
  registerAfterSendEventHook(hook: AnalyticsClientSendEventHook): void;
99
100
  addEventTypeMapping(eventType: string, eventConfig: EventTypeConfig): void;
100
101
  runtime: IRuntimeEnvironment;
102
+ version: string;
101
103
  /**
102
104
  * @deprecated
103
105
  */
@@ -118,6 +120,11 @@ export function buildBaseUrl(endpoint = Endpoints.default, apiVersion = Version)
118
120
  return `${endpoint}${endpointIsCoveoProxy ? '' : '/rest'}/${apiVersion}`;
119
121
  }
120
122
 
123
+ // Note: Changing this value will destroy the mapping from tracking string to clientId for all customers
124
+ // using the setClientId() api. It will have the same effect as every visitor for those customers clearing
125
+ // their cookie store at the same time, with corresponding downstream effects.
126
+ const COVEO_NAMESPACE = '38824e1f-37f5-42d3-8372-a4b8fa9df946';
127
+
121
128
  export class CoveoAnalyticsClient implements AnalyticsClient, VisitorIdProvider {
122
129
  private get defaultOptions(): ClientOptions {
123
130
  return {
@@ -130,6 +137,9 @@ export class CoveoAnalyticsClient implements AnalyticsClient, VisitorIdProvider
130
137
  }
131
138
 
132
139
  public runtime: IRuntimeEnvironment;
140
+ public get version(): string {
141
+ return libVersion;
142
+ }
133
143
  private visitorId: string;
134
144
  private bufferedRequests: BufferedRequest[];
135
145
  private beforeSendHooks: AnalyticsClientSendEventHook[];
@@ -209,6 +219,17 @@ export class CoveoAnalyticsClient implements AnalyticsClient, VisitorIdProvider
209
219
  await this.storage.setItem('visitorId', visitorId);
210
220
  }
211
221
 
222
+ async setClientId(value: string, namespace?: string) {
223
+ if (uuidValidate(value)) {
224
+ this.setCurrentVisitorId(value);
225
+ } else {
226
+ if (!namespace) {
227
+ throw Error('Cannot generate uuid client id without a specific namespace string.');
228
+ }
229
+ this.setCurrentVisitorId(uuidv5(value, uuidv5(namespace, COVEO_NAMESPACE)));
230
+ }
231
+ }
232
+
212
233
  async getParameters(eventType: EventType | string, ...payload: VariableArgumentsPayload) {
213
234
  return await this.resolveParameters(eventType, ...payload);
214
235
  }
@@ -124,7 +124,7 @@ describe('AnalyticsBeaconClient', () => {
124
124
 
125
125
  await client.sendEvent(EventType.collect, {});
126
126
 
127
- expect(clientOrigin).toBe('analyticsBeacon');
127
+ expect(clientOrigin!).toBe('analyticsBeacon');
128
128
  expect(sendBeaconMock).toHaveBeenCalledWith(processedRequest.url, processedRequest.body);
129
129
  });
130
130
 
@@ -17,6 +17,7 @@ import {
17
17
  PreparedViewEventRequest,
18
18
  ViewEventRequest,
19
19
  } from '../events';
20
+ import {libVersion} from '../version';
20
21
  import {NoopRuntime} from './runtimeEnvironment';
21
22
 
22
23
  export class NoopAnalytics implements AnalyticsClient {
@@ -68,5 +69,8 @@ export class NoopAnalytics implements AnalyticsClient {
68
69
  registerAfterSendEventHook(): void {}
69
70
  addEventTypeMapping(): void {}
70
71
  runtime = new NoopRuntime();
72
+ public get version(): string {
73
+ return libVersion;
74
+ }
71
75
  currentVisitorId = '';
72
76
  }
@@ -1,50 +1,27 @@
1
1
  interface CookieDetails {
2
2
  name: string;
3
3
  value: string;
4
- expires: string;
5
- domain: string;
4
+ expirationDate?: Date;
5
+ domain?: string;
6
6
  }
7
7
 
8
- // Code originally taken from : https://developers.livechatinc.com/blog/setting-cookies-to-subdomains-in-javascript/
8
+ // Code originally modified from : https://developers.livechatinc.com/blog/setting-cookies-to-subdomains-in-javascript/
9
9
  export class Cookie {
10
- static set(name: string, value: string, expiration?: number) {
11
- var domain: string, domainParts: string[], date: any, expires: string, host: string;
12
-
13
- if (expiration) {
14
- date = new Date();
15
- date.setTime(date.getTime() + expiration);
16
- expires = '; expires=' + date.toGMTString();
17
- } else {
18
- expires = '';
10
+ static set(name: string, value: string, expire?: number) {
11
+ var domain: string, expirationDate: Date | undefined, domainParts: string[], host: string;
12
+ if (expire) {
13
+ expirationDate = new Date();
14
+ expirationDate.setTime(expirationDate.getTime() + expire);
19
15
  }
20
-
21
16
  host = window.location.hostname;
22
17
  if (host.indexOf('.') === -1) {
23
- // no "." in a domain - it's localhost or something similar
24
- document.cookie = name + '=' + value + expires + '; path=/';
18
+ // no "." in a domain - single domain name, it's localhost or something similar
19
+ writeCookie(name, value, expirationDate);
25
20
  } else {
26
- // Remember the cookie on all subdomains.
27
- //
28
- // Start with trying to set cookie to the top domain.
29
- // (example: if user is on foo.com, try to set
30
- // cookie to domain ".com")
31
- //
32
- // If the cookie will not be set, it means ".com"
33
- // is a top level domain and we need to
34
- // set the cookie to ".foo.com"
35
21
  domainParts = host.split('.');
36
- domainParts.shift();
37
- domain = '.' + domainParts.join('.');
38
-
39
- writeCookie({name, value, expires, domain});
40
-
41
- // check if cookie was successfuly set to the given domain
42
- // (otherwise it was a Top-Level Domain)
43
- if (Cookie.get(name) == null || Cookie.get(name) != value) {
44
- // append "." to current domain
45
- domain = '.' + host;
46
- writeCookie({name, value, expires, domain});
47
- }
22
+ // we always have at least 2 domain parts
23
+ domain = domainParts[domainParts.length - 2] + '.' + domainParts[domainParts.length - 1];
24
+ writeCookie(name, value, expirationDate, domain);
48
25
  }
49
26
  }
50
27
 
@@ -53,9 +30,8 @@ export class Cookie {
53
30
  var cookieArray = document.cookie.split(';');
54
31
  for (var i = 0; i < cookieArray.length; i++) {
55
32
  var cookie = cookieArray[i];
56
- cookie = cookie.replace(/^\s+/, '');
57
-
58
- if (cookie.indexOf(cookiePrefix) == 0) {
33
+ cookie = cookie.replace(/^\s+/, ''); //strip whitespace from front of cookie only
34
+ if (cookie.lastIndexOf(cookiePrefix, 0) === 0) {
59
35
  return cookie.substring(cookiePrefix.length, cookie.length);
60
36
  }
61
37
  }
@@ -67,7 +43,10 @@ export class Cookie {
67
43
  }
68
44
  }
69
45
 
70
- function writeCookie(details: CookieDetails) {
71
- const {name, value, expires, domain} = details;
72
- document.cookie = `${name}=${value}${expires}; path=/; domain=${domain}; SameSite=Lax`;
46
+ function writeCookie(name: string, value: string, expirationDate?: Date, domain?: string) {
47
+ document.cookie =
48
+ `${name}=${value}` +
49
+ (expirationDate ? `;expires=${expirationDate.toUTCString()}` : '') +
50
+ (domain ? `;domain=${domain}` : '') +
51
+ ';SameSite=Lax';
73
52
  }
@@ -4,13 +4,13 @@ import handleOneAnalyticsEvent from './simpleanalytics';
4
4
  declare const self: any;
5
5
 
6
6
  const promise = (window as any)['Promise'];
7
- if (!(promise instanceof Function)) {
7
+ if (!(promise instanceof Function) && !global) {
8
8
  console.error(
9
9
  `This script uses window.Promise which is not supported in your browser. Consider adding a polyfill like "es6-promise".`
10
10
  );
11
11
  }
12
12
  const fetch = (window as any)['fetch'];
13
- if (!(fetch instanceof Function)) {
13
+ if (!(fetch instanceof Function) && !global) {
14
14
  console.error(
15
15
  `This script uses window.fetch which is not supported in your browser. Consider adding a polyfill like "fetch".`
16
16
  );
@@ -20,7 +20,7 @@ export class Plugins {
20
20
  `No plugin named "${name}" is currently registered. If you use a custom plugin, use 'provide' first.`
21
21
  );
22
22
  }
23
- this.requiredPlugins[name] = new pluginClass(options);
23
+ this.requiredPlugins[name] = new (pluginClass as any)(options);
24
24
  }
25
25
 
26
26
  provide(name: string, plugin: PluginClass) {
@@ -1,15 +1,14 @@
1
1
  import coveoua from './simpleanalytics';
2
2
  import {createAnalyticsClientMock, visitorIdMock} from '../../tests/analyticsClientMock';
3
3
  import {TestPlugin} from '../../tests/pluginMock';
4
- import {uuidv4} from '../client/crypto';
4
+ import {v4 as uuidv4} from 'uuid';
5
5
  import {PluginOptions} from '../plugins/BasePlugin';
6
6
  import {mockFetch} from '../../tests/fetchMock';
7
7
  import {CookieStorage} from '../storage';
8
+ import {libVersion} from '../version';
8
9
 
9
10
  const uuidv4Mock = jest.fn();
10
- jest.mock('../client/crypto', () => ({
11
- uuidv4: () => uuidv4Mock(),
12
- }));
11
+ jest.mock('uuid', () => ({v4: () => uuidv4Mock()}));
13
12
 
14
13
  const {fetchMock, fetchMockBeforeEach} = mockFetch();
15
14
 
@@ -376,6 +375,13 @@ describe('simpleanalytics', () => {
376
375
  });
377
376
  });
378
377
 
378
+ describe('version', () => {
379
+ it('returns the current version string', () => {
380
+ coveoua('init', 'MYTOKEN');
381
+ expect(coveoua('version')).toBe(libVersion);
382
+ });
383
+ });
384
+
379
385
  describe('callPlugin', () => {
380
386
  it('resolves properly plugin actions', () => {
381
387
  coveoua('provide', 'test', TestPluginWithSpy);
@@ -468,7 +474,7 @@ describe('simpleanalytics', () => {
468
474
  coveoua('init', 'SOME TOKEN', {plugins: ['svc']});
469
475
 
470
476
  expect(() => coveoua('potato')).toThrow(
471
- `The action "potato" does not exist. Available actions: init, set, send, onLoad, callPlugin, reset, require, provide.`
477
+ `The action "potato" does not exist. Available actions: init, set, send, onLoad, callPlugin, reset, require, provide, version.`
472
478
  );
473
479
  });
474
480
 
@@ -3,6 +3,7 @@ import {AnalyticsClient, CoveoAnalyticsClient, Endpoints} from '../client/analyt
3
3
  import {Plugins} from './plugins';
4
4
  import {PluginOptions} from '../plugins/BasePlugin';
5
5
  import {PluginClass} from '../plugins/BasePlugin';
6
+ import {libVersion} from '../version';
6
7
 
7
8
  export type AvailableActions = keyof CoveoUA;
8
9
 
@@ -137,6 +138,10 @@ export class CoveoUA {
137
138
  this.plugins = new Plugins();
138
139
  this.params = {};
139
140
  }
141
+
142
+ version(): string {
143
+ return libVersion;
144
+ }
140
145
  }
141
146
 
142
147
  export const coveoua = new CoveoUA();
@@ -160,6 +165,7 @@ export const handleOneAnalyticsEvent = (command: string, ...params: any[]) => {
160
165
  'reset',
161
166
  'require',
162
167
  'provide',
168
+ 'version',
163
169
  ];
164
170
  throw new Error(`The action "${command}" does not exist. Available actions: ${actions.join(', ')}.`);
165
171
  }
@@ -1,7 +1,6 @@
1
1
  import {AnalyticsClient} from '../client/analytics';
2
- import {uuidv4} from '../client/crypto';
2
+ import {v4 as uuidv4} from 'uuid';
3
3
  import {getFormattedLocation} from '../client/location';
4
- import {UAPluginOptions} from '../coveoua/plugins';
5
4
  import {hasDocument} from '../detector';
6
5
 
7
6
  type PluginWithId = {
@@ -67,7 +66,7 @@ export abstract class BasePlugin {
67
66
  public getDefaultContextInformation(eventType: string) {
68
67
  const documentContext = {
69
68
  title: hasDocument() ? document.title : '',
70
- encoding: hasDocument() ? document.characterSet :'UTF-8',
69
+ encoding: hasDocument() ? document.characterSet : 'UTF-8',
71
70
  };
72
71
  const screenContext = {
73
72
  screenResolution: `${screen.width}x${screen.height}`,
@@ -103,7 +102,7 @@ export abstract class BasePlugin {
103
102
  }
104
103
 
105
104
  /*
106
- When calling getPayload or getParameters, we need to return what would be sent by the API without updating our internal reference.
105
+ When calling getPayload or getParameters, we need to return what would be sent by the API without updating our internal reference.
107
106
  For instance, if you getPayload("pageview"), we want to return the same payload as if you did coveoua("send", "pageview").
108
107
  */
109
108
  private getNextValues(eventType: string, payload: any) {
@@ -25,7 +25,7 @@ describe('EC plugin', () => {
25
25
  beforeEach(() => {
26
26
  jest.clearAllMocks();
27
27
  client = createAnalyticsClientMock();
28
- ec = new ECPlugin({client, uuidGenerator: someUUIDGenerator});
28
+ ec = new ECPlugin({client, uuidGenerator: someUUIDGenerator as any});
29
29
  });
30
30
 
31
31
  it('should register a hook in the client', () => {
package/src/plugins/ec.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import {EventType} from '../events';
2
- import {uuidv4} from '../client/crypto';
2
+ import {v4 as uuidv4} from 'uuid';
3
3
  import {
4
4
  convertProductToMeasurementProtocol,
5
5
  convertImpressionListToMeasurementProtocol,
@@ -25,7 +25,7 @@ describe('SVC plugin', () => {
25
25
  beforeEach(() => {
26
26
  jest.clearAllMocks();
27
27
  client = createAnalyticsClientMock();
28
- svc = new SVCPlugin({client, uuidGenerator: someUUIDGenerator});
28
+ svc = new SVCPlugin({client, uuidGenerator: someUUIDGenerator as any});
29
29
  });
30
30
 
31
31
  it('should register a hook in the client', () => {
@@ -1,5 +1,5 @@
1
1
  import {EventType} from '../events';
2
- import {uuidv4} from '../client/crypto';
2
+ import {v4 as uuidv4} from 'uuid';
3
3
  import {convertTicketToMeasurementProtocol} from '../client/measurementProtocolMapping/serviceMeasurementProtocolMapper';
4
4
  import {BasePlugin, BasePluginEventTypes, PluginClass, PluginOptions} from './BasePlugin';
5
5
 
@@ -2,7 +2,7 @@ import {WebStorage} from '../storage';
2
2
  import {AnalyticsFetchClient} from '../client/analyticsFetchClient';
3
3
  import {IRuntimeEnvironment} from '../client/runtimeEnvironment';
4
4
  import {PreprocessAnalyticsRequest} from '../client/analyticsRequestClient';
5
- import {uuidv4} from '../client/crypto';
5
+ import {v4 as uuidv4} from 'uuid';
6
6
  import {buildBaseUrl} from '../client/analytics';
7
7
 
8
8
  export type ReactNativeStorage = WebStorage;
@@ -1,4 +1,5 @@
1
1
  import {CookieStorage, CookieAndLocalStorage} from './storage';
2
+ import {Cookie} from './cookieutils';
2
3
 
3
4
  describe('CookieStorage', () => {
4
5
  const key = 'wow';
@@ -16,6 +17,13 @@ describe('CookieStorage', () => {
16
17
  storage.removeItem(key);
17
18
  expect(storage.getItem(key)).toBe(null);
18
19
  });
20
+
21
+ it('honors expiration date', async () => {
22
+ const storage = new CookieStorage();
23
+ storage.setItem(key, someData, 1000);
24
+ await new Promise((res) => setTimeout(res, 1000)); // wait for 1 sec
25
+ expect(storage.getItem(key)).toBe(null);
26
+ });
19
27
  });
20
28
 
21
29
  describe('CookieAndLocalStorage', () => {
package/src/storage.ts CHANGED
@@ -33,8 +33,8 @@ export class CookieStorage implements WebStorage {
33
33
  removeItem(key: string) {
34
34
  Cookie.erase(`${CookieStorage.prefix}${key}`);
35
35
  }
36
- setItem(key: string, data: string): void {
37
- Cookie.set(`${CookieStorage.prefix}${key}`, data);
36
+ setItem(key: string, data: string, expire?: number): void {
37
+ Cookie.set(`${CookieStorage.prefix}${key}`, data, expire);
38
38
  }
39
39
  }
40
40
 
@@ -52,7 +52,7 @@ export class CookieAndLocalStorage implements WebStorage {
52
52
 
53
53
  setItem(key: string, data: string): void {
54
54
  localStorage.setItem(key, data);
55
- this.cookieStorage.setItem(key, data);
55
+ this.cookieStorage.setItem(key, data, 31556926000); // 1 year first party cookie
56
56
  }
57
57
  }
58
58
 
package/src/version.ts ADDED
@@ -0,0 +1 @@
1
+ export const libVersion = process.env.PKG_VERSION || 'local'; // processed by @rollup/plugin-replace
@@ -1 +0,0 @@
1
- export declare const uuidv4: (a?: string | number | undefined) => string;
@@ -1,21 +0,0 @@
1
- import {hasCryptoRandomValues} from '../detector';
2
-
3
- export const uuidv4 = (a?: number | string): string => {
4
- if (!!a) {
5
- return (Number(a) ^ (getRandomValues(new Uint8Array(1))[0] % 16 >> (Number(a) / 4))).toString(16);
6
- }
7
- return (`${1e7}` + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuidv4);
8
- };
9
-
10
- const getRandomValues = (rnds: Uint8Array) => {
11
- if (hasCryptoRandomValues()) {
12
- return crypto.getRandomValues(rnds);
13
- }
14
- for (var i = 0, r = 0; i < rnds.length; i++) {
15
- if ((i & 0x03) === 0) {
16
- r = Math.random() * 0x100000000;
17
- }
18
- rnds[i] = (r >>> ((i & 0x03) << 3)) & 0xff;
19
- }
20
- return rnds;
21
- };