kv-test-lib 1.0.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.
@@ -0,0 +1,8 @@
1
+ export declare const getPackageName: () => string;
2
+ export declare const getLanguage: () => string;
3
+ export declare const getDeviceWidth: () => number;
4
+ export declare const getDeviceHeight: () => number;
5
+ export declare const getDeviceOrientation: () => string;
6
+ export declare const getBaseDomain: () => string;
7
+ export declare const getPageName: () => string;
8
+ export declare const getUrlParameter: (name: string) => string;
@@ -0,0 +1,40 @@
1
+ /*
2
+ Authored by Brett Barinaga on 11/17/21.
3
+ Copyright (c) Kochava, Inc. All rights reserved.
4
+ */
5
+ export const getPackageName = () => `com.${window.location.hostname}.web`;
6
+ export const getLanguage = () => (navigator) ? navigator.language : "";
7
+ export const getDeviceWidth = () => (window) ? window.screen.availWidth : 0;
8
+ export const getDeviceHeight = () => (window) ? window.screen.availHeight : 0;
9
+ export const getDeviceOrientation = () => (window) ? window.innerWidth < window.innerHeight
10
+ ? "portrait" : "landscape" : "";
11
+ export const getBaseDomain = () => {
12
+ try {
13
+ const regexResult = window.location.host.match(/[^.]*\.[^.]*$/);
14
+ if (regexResult)
15
+ return regexResult[0];
16
+ return "";
17
+ }
18
+ catch (err) {
19
+ return window.location.host;
20
+ }
21
+ };
22
+ export const getPageName = () => {
23
+ let page = "";
24
+ if (window.location) {
25
+ page = window.location.pathname.substring(1);
26
+ page = page.replace(/\/+$/, "");
27
+ }
28
+ return page === "" ? "/" : page;
29
+ };
30
+ export const getUrlParameter = (name) => {
31
+ if (!window.location || !window.location.search) {
32
+ return "";
33
+ }
34
+ name = name.replace(/[[]/, "\\[").replace(/[\]]/, "\\]");
35
+ const regex = new RegExp("[\\?&]" + name + "=([^&#]*)");
36
+ const results = regex.exec(window.location.search);
37
+ return results === null
38
+ ? ""
39
+ : decodeURIComponent(results[1].replace(/\+/g, " "));
40
+ };
@@ -0,0 +1,3 @@
1
+ export declare const setCookie: (name: string, value: string) => void;
2
+ export declare const getCookie: (name: string) => string;
3
+ export declare const deleteCookie: (name: string) => void;
@@ -0,0 +1,40 @@
1
+ /*
2
+ Authored by Brett Barinaga on 11/17/21.
3
+ Copyright (c) Kochava, Inc. All rights reserved.
4
+ */
5
+ import { getBaseDomain } from "./browser";
6
+ export const setCookie = (name, value) => {
7
+ let expires = "";
8
+ const date = new Date();
9
+ date.setTime(date.getTime() + 3650 * 24 * 60 * 60 * 1000);
10
+ expires = `; expires=${date.toUTCString()}`;
11
+ document.cookie =
12
+ name +
13
+ "=" +
14
+ (value || "") +
15
+ expires +
16
+ "; path=/;domain=" +
17
+ getBaseDomain();
18
+ };
19
+ export const getCookie = (name) => {
20
+ const nameEQ = name + "=";
21
+ const charArray = document.cookie.split(';');
22
+ for (let i = 0; i < charArray.length; i++) {
23
+ let char = charArray[i];
24
+ while (char.charAt(0) === " ")
25
+ char = char.substring(1, char.length);
26
+ if (char.indexOf(nameEQ) === 0)
27
+ return char.substring(nameEQ.length, char.length);
28
+ }
29
+ return "";
30
+ };
31
+ export const deleteCookie = (name) => {
32
+ if (getCookie(name)) {
33
+ const path = "/";
34
+ const domain = getBaseDomain();
35
+ document.cookie = name + "=" +
36
+ ((path) ? ";path=" + path : "") +
37
+ ((domain) ? ";domain=" + domain : "") +
38
+ ";expires=Thu, 01 Jan 1970 00:00:01 GMT";
39
+ }
40
+ };
@@ -0,0 +1,33 @@
1
+ import { IdentityLink } from "../interfaces";
2
+ import { EventJob, IdLinkJob } from "../jobqueue";
3
+ export declare const MAX_STORED_IDLINKS = 10;
4
+ export declare enum PersistKey {
5
+ LastKvinit = "com.kochava.tracker.LastKvinit",
6
+ EventQueue = "com.kochava.tracker.EventQueue",
7
+ IdLinkQueue = "com.kochava.tracker.IdLinkQueue",
8
+ DeviceId = "com.kochava.tracker.DeviceId",
9
+ InstallId = "com.kochava.tracker.InstallId",
10
+ FirstStartDate = "com.kochava.tracker.FirstStartDate",
11
+ InstallSentDate = "com.kochava.tracker.InstallSentDate",
12
+ KvinitSentDate = "com.kochava.tracker.KvinitSentDate",
13
+ SessionCount = "com.kochava.tracker.SessionCount",
14
+ IdentityLinks = "com.kochava.tracker.IdentityLinks",
15
+ OverrideAppId = "com.kochava.tracker.OverrideAppId",
16
+ OverrideDeviceId = "com.kochava.tracker.OverrideDeviceId",
17
+ OldKvid = "kv_id"
18
+ }
19
+ export declare const checkInstallIdChange: (inputId: string, useCookies: boolean) => boolean;
20
+ export declare const addToPersistedEventQueue: (job: EventJob) => void;
21
+ export declare const removeFromEventPersistedQueue: (job: EventJob) => void;
22
+ export declare const updateOrAddPersistedIdLinkQueue: (job: IdLinkJob) => void;
23
+ export declare const removeFromIdLinkPersistedQueue: (job: IdLinkJob) => void;
24
+ export declare const addPersistedIdLinks: (key: string, value: string, useCookies: boolean) => void;
25
+ export declare const checkDuplicateIdLink: (key: string, value: string) => boolean;
26
+ export declare const getPersistedIdentityLinks: () => IdentityLink | undefined;
27
+ export declare const readAndUpdateUTM: (appGuid: string, useCookies: boolean) => string;
28
+ export declare const readAndUpdatePersistedValue: (key: PersistKey, useCookie: boolean) => string;
29
+ export declare const updatePersistedValue: (key: PersistKey, value: string, useCookie: boolean) => void;
30
+ export declare const deletePersistedValue: (item: PersistKey) => void;
31
+ export declare const deleteAllPersisted: () => void;
32
+ export declare const readAndUpdateDeviceId: (useCookie: boolean) => string;
33
+ export declare const readAndUpdateSessionCount: (useCookie: boolean) => number;
@@ -0,0 +1,195 @@
1
+ /*
2
+ Authored by Brett Barinaga on 11/17/21.
3
+ Copyright (c) Kochava, Inc. All rights reserved.
4
+ */
5
+ import * as utils from "../utils/utils";
6
+ import { getUrlParameter } from "./browser";
7
+ import { setCookie, getCookie, deleteCookie } from "./cookies";
8
+ import { Log } from "../utils/log";
9
+ export const MAX_STORED_IDLINKS = 10;
10
+ export var PersistKey;
11
+ (function (PersistKey) {
12
+ PersistKey["LastKvinit"] = "com.kochava.tracker.LastKvinit";
13
+ PersistKey["EventQueue"] = "com.kochava.tracker.EventQueue";
14
+ PersistKey["IdLinkQueue"] = "com.kochava.tracker.IdLinkQueue";
15
+ PersistKey["DeviceId"] = "com.kochava.tracker.DeviceId";
16
+ PersistKey["InstallId"] = "com.kochava.tracker.InstallId";
17
+ PersistKey["FirstStartDate"] = "com.kochava.tracker.FirstStartDate";
18
+ PersistKey["InstallSentDate"] = "com.kochava.tracker.InstallSentDate";
19
+ PersistKey["KvinitSentDate"] = "com.kochava.tracker.KvinitSentDate";
20
+ PersistKey["SessionCount"] = "com.kochava.tracker.SessionCount";
21
+ PersistKey["IdentityLinks"] = "com.kochava.tracker.IdentityLinks";
22
+ PersistKey["OverrideAppId"] = "com.kochava.tracker.OverrideAppId";
23
+ PersistKey["OverrideDeviceId"] = "com.kochava.tracker.OverrideDeviceId";
24
+ PersistKey["OldKvid"] = "kv_id";
25
+ })(PersistKey || (PersistKey = {}));
26
+ const storedKeys = [
27
+ PersistKey.LastKvinit,
28
+ PersistKey.EventQueue,
29
+ PersistKey.IdLinkQueue,
30
+ PersistKey.DeviceId,
31
+ PersistKey.InstallId,
32
+ PersistKey.FirstStartDate,
33
+ PersistKey.InstallSentDate,
34
+ PersistKey.KvinitSentDate,
35
+ PersistKey.SessionCount,
36
+ PersistKey.IdentityLinks,
37
+ PersistKey.OverrideAppId,
38
+ PersistKey.OverrideDeviceId,
39
+ ];
40
+ export const checkInstallIdChange = (inputId, useCookies) => {
41
+ const persistedInstallId = readAndUpdatePersistedValue(PersistKey.InstallId, useCookies);
42
+ // if the input is empty, we don't need to change
43
+ if (!inputId)
44
+ return false;
45
+ // if the persistedId is empty, we will need to change
46
+ if (!persistedInstallId) {
47
+ updatePersistedValue(PersistKey.InstallId, inputId, useCookies);
48
+ return true;
49
+ }
50
+ // if the inputId and persistedId are the same, we dont need to change
51
+ if (inputId === persistedInstallId)
52
+ return false;
53
+ // at this point both inputId and persistedInstallId exist and are not equal,
54
+ // so we must need to change
55
+ updatePersistedValue(PersistKey.InstallId, inputId, useCookies);
56
+ return true;
57
+ };
58
+ export const addToPersistedEventQueue = (job) => {
59
+ const persistedQueueStr = localStorage.getItem(PersistKey.EventQueue);
60
+ const persistedQueue = JSON.parse(persistedQueueStr) || [];
61
+ persistedQueue.push(job);
62
+ localStorage.setItem(PersistKey.EventQueue, JSON.stringify(persistedQueue));
63
+ };
64
+ export const removeFromEventPersistedQueue = (job) => {
65
+ const persistedQueueStr = localStorage.getItem(PersistKey.EventQueue);
66
+ const persistedQueue = JSON.parse(persistedQueueStr) || [];
67
+ const queueWithJobRemoved = persistedQueue.filter(persistedJob => {
68
+ return persistedJob.id !== job.id;
69
+ });
70
+ localStorage.setItem(PersistKey.EventQueue, JSON.stringify(queueWithJobRemoved));
71
+ };
72
+ export const updateOrAddPersistedIdLinkQueue = (job) => {
73
+ const idLinkKey = Object.keys(job.idLink)[0];
74
+ const persistedQueueStr = localStorage.getItem(PersistKey.IdLinkQueue);
75
+ const persistedQueue = JSON.parse(persistedQueueStr) || [];
76
+ let updated = false;
77
+ for (const persistedJob of persistedQueue) {
78
+ const persistedKey = Object.keys(persistedJob.idLink)[0];
79
+ // if the key is already there, update it
80
+ if (idLinkKey === persistedKey) {
81
+ persistedJob.idLink[idLinkKey] = job.idLink[idLinkKey];
82
+ updated = true;
83
+ }
84
+ }
85
+ // if the key is new, add it
86
+ if (!updated)
87
+ persistedQueue.push(job);
88
+ localStorage.setItem(PersistKey.IdLinkQueue, JSON.stringify(persistedQueue));
89
+ };
90
+ export const removeFromIdLinkPersistedQueue = (job) => {
91
+ const persistedQueueStr = localStorage.getItem(PersistKey.IdLinkQueue);
92
+ const persistedQueue = JSON.parse(persistedQueueStr) || [];
93
+ const queueWithJobRemoved = persistedQueue.filter(persistedJob => {
94
+ return persistedJob.id !== job.id;
95
+ });
96
+ localStorage.setItem(PersistKey.IdLinkQueue, JSON.stringify(queueWithJobRemoved));
97
+ };
98
+ export const addPersistedIdLinks = (key, value, useCookies) => {
99
+ const persistedIdLinksStr = localStorage.getItem(PersistKey.IdentityLinks);
100
+ const persistedIdLinks = JSON.parse(persistedIdLinksStr) || {};
101
+ const storedSoFar = Object.keys(persistedIdLinks);
102
+ if (storedSoFar.length > MAX_STORED_IDLINKS) {
103
+ Log.debug("Maximum stored idLinks reached, most recent idLink will not be stored.");
104
+ return;
105
+ }
106
+ persistedIdLinks[key] = value;
107
+ updatePersistedValue(PersistKey.IdentityLinks, JSON.stringify(persistedIdLinks), useCookies);
108
+ };
109
+ export const checkDuplicateIdLink = (key, value) => {
110
+ const persistedIdLinksStr = localStorage.getItem(PersistKey.IdentityLinks);
111
+ if (persistedIdLinksStr) {
112
+ const persistedIdLinks = JSON.parse(persistedIdLinksStr) || {};
113
+ for (const persistedKey in persistedIdLinks) {
114
+ if (key === persistedKey && persistedIdLinks[persistedKey] === value) {
115
+ return true;
116
+ }
117
+ }
118
+ }
119
+ return false;
120
+ };
121
+ export const getPersistedIdentityLinks = () => {
122
+ const persistedIdLinksStr = localStorage.getItem(PersistKey.IdentityLinks);
123
+ if (persistedIdLinksStr) {
124
+ return JSON.parse(persistedIdLinksStr);
125
+ }
126
+ return undefined;
127
+ };
128
+ export const readAndUpdateUTM = (appGuid, useCookies) => {
129
+ const storageName = appGuid + "_click";
130
+ const urlValue = getUrlParameter("ko_click_id");
131
+ const storageValue = localStorage.getItem(storageName);
132
+ let cookieValue = "";
133
+ if (useCookies)
134
+ cookieValue = getCookie(storageName);
135
+ if (urlValue) {
136
+ localStorage.setItem(storageName, urlValue);
137
+ if (useCookies)
138
+ setCookie(storageName, urlValue);
139
+ }
140
+ else if (storageValue) {
141
+ if (useCookies)
142
+ setCookie(storageName, urlValue);
143
+ }
144
+ return (urlValue) ? urlValue :
145
+ (storageValue) ? storageValue :
146
+ (cookieValue) ? cookieValue : "";
147
+ };
148
+ export const readAndUpdatePersistedValue = (key, useCookie) => {
149
+ const urlValue = getUrlParameter(key);
150
+ const storageValue = localStorage.getItem(key);
151
+ let cookieValue = "";
152
+ if (useCookie)
153
+ cookieValue = getCookie(key);
154
+ if (urlValue) {
155
+ updatePersistedValue(key, urlValue, useCookie);
156
+ }
157
+ else if (storageValue) {
158
+ updatePersistedValue(key, storageValue, useCookie);
159
+ }
160
+ else if (cookieValue) {
161
+ updatePersistedValue(key, storageValue, useCookie);
162
+ }
163
+ return (urlValue) ? urlValue :
164
+ (storageValue) ? storageValue :
165
+ (cookieValue) ? cookieValue : "";
166
+ };
167
+ export const updatePersistedValue = (key, value, useCookie) => {
168
+ localStorage.setItem(key, value);
169
+ if (useCookie)
170
+ setCookie(key, value);
171
+ };
172
+ export const deletePersistedValue = (item) => {
173
+ localStorage.removeItem(item);
174
+ deleteCookie(item);
175
+ };
176
+ export const deleteAllPersisted = () => storedKeys.forEach(item => deletePersistedValue(item));
177
+ export const readAndUpdateDeviceId = (useCookie) => {
178
+ let storedDeviceId = readAndUpdatePersistedValue(PersistKey.DeviceId, useCookie);
179
+ if (!storedDeviceId) {
180
+ const kvId = `KB${utils.getCurrTimeSec()}T${utils.uuidv4()}`;
181
+ storedDeviceId = kvId.replace(/-/g, "");
182
+ }
183
+ updatePersistedValue(PersistKey.DeviceId, storedDeviceId, useCookie);
184
+ return storedDeviceId;
185
+ };
186
+ export const readAndUpdateSessionCount = (useCookie) => {
187
+ const storedSessionCount = readAndUpdatePersistedValue(PersistKey.SessionCount, useCookie);
188
+ let sessionCount = 1;
189
+ if (storedSessionCount) {
190
+ sessionCount = parseInt(storedSessionCount);
191
+ sessionCount++;
192
+ }
193
+ updatePersistedValue(PersistKey.SessionCount, sessionCount.toString(), useCookie);
194
+ return sessionCount;
195
+ };
package/dist/http.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { Payload } from "./payloads/payload";
2
+ export interface BaseResp {
3
+ success: string | number | boolean;
4
+ }
5
+ export declare const sendRequest: (payload: Payload, endpoint: string) => Promise<string>;
6
+ export declare const wasRespSuccess: (success: string | number | boolean) => boolean;
package/dist/http.js ADDED
@@ -0,0 +1,23 @@
1
+ /*
2
+ Authored by Brett Barinaga on 11/17/21.
3
+ Copyright (c) Kochava, Inc. All rights reserved.
4
+ */
5
+ import { Log } from "./utils/log";
6
+ export const sendRequest = async (payload, endpoint) => {
7
+ try {
8
+ const headers = new Headers();
9
+ headers.append("Content-Type", "application/json");
10
+ Log.trace(`Request ${payload.nt_id} being sent to: `, endpoint);
11
+ const resp = await fetch(endpoint, {
12
+ method: "POST",
13
+ headers: headers,
14
+ body: JSON.stringify(payload),
15
+ });
16
+ return await resp.text();
17
+ }
18
+ catch (e) {
19
+ Log.error("Error in post request", e);
20
+ return "";
21
+ }
22
+ };
23
+ export const wasRespSuccess = (success) => success === "1" || success === 1 || success === true;
@@ -0,0 +1,117 @@
1
+ interface DefaultConfig {
2
+ readonly general: {
3
+ readonly app_id_override: string;
4
+ readonly device_id_override: string;
5
+ };
6
+ readonly config: {
7
+ readonly init_token: string;
8
+ readonly refresh_minimum: number;
9
+ };
10
+ readonly install: {
11
+ readonly resend_id: "";
12
+ readonly updates_enabled: true;
13
+ };
14
+ readonly networking: {
15
+ readonly urls: {
16
+ readonly init: "https://kvinit-prod.api.kochava.com/track/kvinit";
17
+ readonly install: "https://web-sdk.control.kochava.com/track/json/";
18
+ readonly event: "https://web-sdk.control.kochava.com/track/json/";
19
+ readonly identityLink: "https://web-sdk.control.kochava.com/v1/cpi/identityLink.php";
20
+ };
21
+ readonly retry_waterfall: [7, 30, 300, 1800];
22
+ };
23
+ readonly privacy: {
24
+ readonly allow_custom_ids: string[];
25
+ readonly deny_datapoints: string[];
26
+ readonly deny_event_names: string[];
27
+ readonly deny_identity_links: string[];
28
+ };
29
+ }
30
+ export declare const DEFAULTS: DefaultConfig;
31
+ export interface KvConfig {
32
+ general: {
33
+ device_id_override?: string;
34
+ app_id_override?: string;
35
+ };
36
+ config: {
37
+ init_token: string;
38
+ refresh_minimum: number;
39
+ };
40
+ install: {
41
+ resend_id?: string;
42
+ updates_enabled: boolean;
43
+ };
44
+ networking: {
45
+ urls: {
46
+ init: string;
47
+ install: string;
48
+ identityLink: string;
49
+ event: string;
50
+ };
51
+ retry_waterfall: number[];
52
+ };
53
+ privacy: {
54
+ allow_custom_ids: string[];
55
+ deny_datapoints: string[];
56
+ deny_event_names: string[];
57
+ deny_identity_links: string[];
58
+ };
59
+ }
60
+ export interface KvinitResponse {
61
+ general?: {
62
+ device_id_override?: string;
63
+ app_id_override?: string;
64
+ };
65
+ config?: {
66
+ init_token?: string;
67
+ refresh_minimum?: number;
68
+ };
69
+ install?: {
70
+ resend_id?: string;
71
+ updates_enabled?: boolean;
72
+ };
73
+ networking?: {
74
+ urls?: {
75
+ init?: string;
76
+ install?: string;
77
+ identityLink?: string;
78
+ event?: string;
79
+ };
80
+ retry_waterfall?: number[];
81
+ };
82
+ privacy?: {
83
+ allow_custom_ids?: string[];
84
+ deny_datapoints?: string[];
85
+ deny_event_names?: string[];
86
+ deny_identity_links?: string[];
87
+ };
88
+ success?: string | number | boolean;
89
+ }
90
+ export declare type Json = {
91
+ [key: string]: any;
92
+ };
93
+ export declare type IdentityLink = {
94
+ [key: string]: string;
95
+ };
96
+ export interface Urls {
97
+ init: string;
98
+ install: string;
99
+ event: string;
100
+ identityLink: string;
101
+ }
102
+ export interface OverrideUrls {
103
+ init?: string;
104
+ install?: string;
105
+ event?: string;
106
+ identityLink?: string;
107
+ }
108
+ export interface CustomValue {
109
+ data: Json;
110
+ isDeviceId: boolean;
111
+ }
112
+ export interface WrapperVersion {
113
+ name: string;
114
+ version: string;
115
+ build_date: string;
116
+ }
117
+ export {};
@@ -0,0 +1,36 @@
1
+ /*
2
+ Authored by Brett Barinaga on 11/17/21.
3
+ Copyright (c) Kochava, Inc. All rights reserved.
4
+ */
5
+ export const DEFAULTS = {
6
+ general: {
7
+ // DO NOT DEFAULT
8
+ app_id_override: "",
9
+ // DO NOT DEFAULT
10
+ device_id_override: "",
11
+ },
12
+ config: {
13
+ init_token: "",
14
+ refresh_minimum: 60,
15
+ },
16
+ install: {
17
+ // DO NOT DEFAULT
18
+ resend_id: "",
19
+ updates_enabled: true,
20
+ },
21
+ networking: {
22
+ urls: {
23
+ init: "https://kvinit-prod.api.kochava.com/track/kvinit",
24
+ install: "https://web-sdk.control.kochava.com/track/json/",
25
+ event: "https://web-sdk.control.kochava.com/track/json/",
26
+ identityLink: "https://web-sdk.control.kochava.com/v1/cpi/identityLink.php"
27
+ },
28
+ retry_waterfall: [7, 30, 300, 1800],
29
+ },
30
+ privacy: {
31
+ allow_custom_ids: [],
32
+ deny_datapoints: [],
33
+ deny_event_names: [],
34
+ deny_identity_links: [],
35
+ },
36
+ };
@@ -0,0 +1,35 @@
1
+ import { IdentityLink, Json } from "./interfaces";
2
+ import { KochavaInstance } from "./kochava";
3
+ import { PostStartBody, PreStartBody } from "./payloads/payload";
4
+ export interface Job {
5
+ id: string;
6
+ queuedBeforeStart: boolean;
7
+ preStartBody: PreStartBody;
8
+ postStartBody: PostStartBody;
9
+ retries: number;
10
+ }
11
+ export interface EventJob extends Job {
12
+ eventName: string;
13
+ }
14
+ export interface IdLinkJob extends Job {
15
+ idLink: IdentityLink;
16
+ }
17
+ export default class JobQueue {
18
+ private eventQueue;
19
+ idLinkQueue: IdLinkJob[];
20
+ private processing;
21
+ private stopped;
22
+ private paused;
23
+ private timeOut;
24
+ constructor();
25
+ start(instance: KochavaInstance): Promise<void>;
26
+ stop(): void;
27
+ pause(): void;
28
+ enqueueEvent(instance: KochavaInstance, args: [string, Json | string]): Promise<void>;
29
+ enqueueIdLink(instance: KochavaInstance, idLink: IdentityLink): Promise<void>;
30
+ dequeueJob(instance: KochavaInstance): Promise<boolean>;
31
+ processJob(instance: KochavaInstance, job: EventJob | IdLinkJob): Promise<boolean>;
32
+ attemptJob(instance: KochavaInstance, job: Job): Promise<boolean>;
33
+ updateEventJobs(instance: KochavaInstance): void;
34
+ updateIdLinkJobs(instance: KochavaInstance): void;
35
+ }