@cuemath/web-utils 1.0.8 → 1.0.9-deepak.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 (122) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc.json +9 -0
  3. package/.husky/pre-commit +5 -0
  4. package/.huskyrc +5 -0
  5. package/.lintstagedrc.yml +1 -0
  6. package/.nvmrc +1 -0
  7. package/.prettierrc.json +1 -0
  8. package/.vscode/settings.json +1 -0
  9. package/dist/constants/country/index.js.map +1 -0
  10. package/dist/constants/country/iso-country-code.js.map +1 -0
  11. package/dist/constants/date-time/index.js.map +1 -0
  12. package/dist/constants/date-time/international-timezones.js.map +1 -0
  13. package/dist/constants/index.js.map +1 -0
  14. package/dist/cookie/index.js.map +1 -0
  15. package/dist/{cjs/date-time-helper → date-time-helper}/index.js +1 -1
  16. package/dist/date-time-helper/index.js.map +1 -0
  17. package/dist/e-cna/index.js.map +1 -0
  18. package/dist/{cjs/growth-source → growth-source}/index.d.ts +1 -0
  19. package/dist/{cjs/growth-source → growth-source}/index.js +15 -0
  20. package/dist/growth-source/index.js.map +1 -0
  21. package/dist/{cjs/growth-source → growth-source}/types.js.map +1 -1
  22. package/dist/growth-source/utils/env-mode.d.ts +5 -0
  23. package/dist/growth-source/utils/env-mode.js +9 -0
  24. package/dist/growth-source/utils/env-mode.js.map +1 -0
  25. package/dist/growth-source/utils/index.d.ts +2 -0
  26. package/dist/growth-source/utils/index.js +19 -0
  27. package/dist/growth-source/utils/index.js.map +1 -0
  28. package/dist/growth-source/utils/server.d.ts +1 -0
  29. package/dist/growth-source/utils/server.js +5 -0
  30. package/dist/growth-source/utils/server.js.map +1 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/local-storage/index.js.map +1 -0
  33. package/dist/object/index.js.map +1 -0
  34. package/package.json +4 -11
  35. package/src/constants/country/iso-country-code.ts +248 -0
  36. package/src/constants/date-time/index.ts +45 -0
  37. package/src/constants/date-time/international-timezones.ts +157 -0
  38. package/src/cookie/index.ts +59 -0
  39. package/src/date-time-helper/index.ts +139 -0
  40. package/src/e-cna/index.ts +23 -0
  41. package/src/growth-source/index.ts +237 -0
  42. package/src/growth-source/types.ts +50 -0
  43. package/src/growth-source/utils/env-mode.ts +5 -0
  44. package/src/growth-source/utils/index.ts +2 -0
  45. package/src/growth-source/utils/server.ts +1 -0
  46. package/src/local-storage/index.ts +196 -0
  47. package/src/object/index.ts +21 -0
  48. package/tsconfig.json +8 -0
  49. package/dist/cjs/constants/country/index.js.map +0 -1
  50. package/dist/cjs/constants/country/iso-country-code.js.map +0 -1
  51. package/dist/cjs/constants/date-time/index.js.map +0 -1
  52. package/dist/cjs/constants/date-time/international-timezones.js.map +0 -1
  53. package/dist/cjs/constants/index.js.map +0 -1
  54. package/dist/cjs/cookie/index.js.map +0 -1
  55. package/dist/cjs/date-time-helper/index.js.map +0 -1
  56. package/dist/cjs/e-cna/index.js.map +0 -1
  57. package/dist/cjs/growth-source/index.js.map +0 -1
  58. package/dist/cjs/index.js.map +0 -1
  59. package/dist/cjs/local-storage/index.js.map +0 -1
  60. package/dist/cjs/object/index.js.map +0 -1
  61. package/dist/esm/constants/country/index.js +0 -2
  62. package/dist/esm/constants/country/index.js.map +0 -1
  63. package/dist/esm/constants/country/iso-country-code.d.ts +0 -248
  64. package/dist/esm/constants/country/iso-country-code.js +0 -249
  65. package/dist/esm/constants/country/iso-country-code.js.map +0 -1
  66. package/dist/esm/constants/date-time/index.d.ts +0 -18
  67. package/dist/esm/constants/date-time/index.js +0 -40
  68. package/dist/esm/constants/date-time/index.js.map +0 -1
  69. package/dist/esm/constants/date-time/international-timezones.d.ts +0 -7
  70. package/dist/esm/constants/date-time/international-timezones.js +0 -148
  71. package/dist/esm/constants/date-time/international-timezones.js.map +0 -1
  72. package/dist/esm/constants/index.js +0 -3
  73. package/dist/esm/constants/index.js.map +0 -1
  74. package/dist/esm/cookie/index.d.ts +0 -4
  75. package/dist/esm/cookie/index.js +0 -38
  76. package/dist/esm/cookie/index.js.map +0 -1
  77. package/dist/esm/date-time-helper/index.d.ts +0 -30
  78. package/dist/esm/date-time-helper/index.js +0 -87
  79. package/dist/esm/date-time-helper/index.js.map +0 -1
  80. package/dist/esm/e-cna/index.d.ts +0 -4
  81. package/dist/esm/e-cna/index.js +0 -18
  82. package/dist/esm/e-cna/index.js.map +0 -1
  83. package/dist/esm/growth-source/index.d.ts +0 -6
  84. package/dist/esm/growth-source/index.js +0 -180
  85. package/dist/esm/growth-source/index.js.map +0 -1
  86. package/dist/esm/growth-source/types.d.ts +0 -41
  87. package/dist/esm/growth-source/types.js +0 -2
  88. package/dist/esm/growth-source/types.js.map +0 -1
  89. package/dist/esm/index.js +0 -8
  90. package/dist/esm/index.js.map +0 -1
  91. package/dist/esm/local-storage/index.d.ts +0 -13
  92. package/dist/esm/local-storage/index.js +0 -162
  93. package/dist/esm/local-storage/index.js.map +0 -1
  94. package/dist/esm/object/index.d.ts +0 -2
  95. package/dist/esm/object/index.js +0 -19
  96. package/dist/esm/object/index.js.map +0 -1
  97. /package/dist/{cjs/constants → constants}/country/index.d.ts +0 -0
  98. /package/dist/{cjs/constants → constants}/country/index.js +0 -0
  99. /package/dist/{cjs/constants → constants}/country/iso-country-code.d.ts +0 -0
  100. /package/dist/{cjs/constants → constants}/country/iso-country-code.js +0 -0
  101. /package/dist/{cjs/constants → constants}/date-time/index.d.ts +0 -0
  102. /package/dist/{cjs/constants → constants}/date-time/index.js +0 -0
  103. /package/dist/{cjs/constants → constants}/date-time/international-timezones.d.ts +0 -0
  104. /package/dist/{cjs/constants → constants}/date-time/international-timezones.js +0 -0
  105. /package/dist/{cjs/constants → constants}/index.d.ts +0 -0
  106. /package/dist/{cjs/constants → constants}/index.js +0 -0
  107. /package/dist/{cjs/cookie → cookie}/index.d.ts +0 -0
  108. /package/dist/{cjs/cookie → cookie}/index.js +0 -0
  109. /package/dist/{cjs/date-time-helper → date-time-helper}/index.d.ts +0 -0
  110. /package/dist/{cjs/e-cna → e-cna}/index.d.ts +0 -0
  111. /package/dist/{cjs/e-cna → e-cna}/index.js +0 -0
  112. /package/dist/{cjs/growth-source → growth-source}/types.d.ts +0 -0
  113. /package/dist/{cjs/growth-source → growth-source}/types.js +0 -0
  114. /package/dist/{cjs/index.d.ts → index.d.ts} +0 -0
  115. /package/dist/{cjs/index.js → index.js} +0 -0
  116. /package/dist/{cjs/local-storage → local-storage}/index.d.ts +0 -0
  117. /package/dist/{cjs/local-storage → local-storage}/index.js +0 -0
  118. /package/dist/{cjs/object → object}/index.d.ts +0 -0
  119. /package/dist/{cjs/object → object}/index.js +0 -0
  120. /package/{dist/esm/constants/country/index.d.ts → src/constants/country/index.ts} +0 -0
  121. /package/{dist/esm/constants/index.d.ts → src/constants/index.ts} +0 -0
  122. /package/{dist/esm/index.d.ts → src/index.ts} +0 -0
@@ -0,0 +1,157 @@
1
+ interface Timezone {
2
+ id: string;
3
+ value: string;
4
+ meta: string;
5
+ }
6
+
7
+ export const timezones: Timezone[] = [
8
+ {
9
+ id: 'Pacific/Honolulu',
10
+ value: 'HST(GMT-10)',
11
+ meta: 'HST(GMT-10)',
12
+ },
13
+ {
14
+ id: 'America/Anchorage',
15
+ value: 'AST(GMT-9)',
16
+ meta: 'AST(GMT-9)',
17
+ },
18
+ {
19
+ id: 'America/Los_Angeles',
20
+ value: 'PST(GMT-8)',
21
+ meta: 'PST(GMT-8)',
22
+ },
23
+ {
24
+ id: 'America/Denver',
25
+ value: 'MST(GMT-7)',
26
+ meta: 'MST(GMT-7)',
27
+ },
28
+ {
29
+ id: 'America/Phoenix',
30
+ value: 'MST(GMT-7)',
31
+ meta: 'MST(GMT-7)',
32
+ },
33
+ {
34
+ id: 'America/Matamoros',
35
+ value: 'CST(GMT-6)',
36
+ meta: 'CST(GMT-6)',
37
+ },
38
+ {
39
+ id: 'America/New_York',
40
+ value: 'EST(GMT-5)',
41
+ meta: 'EST(GMT-5)',
42
+ },
43
+ {
44
+ id: 'America/Glace_Bay',
45
+ value: 'AST(GMT-4)',
46
+ meta: 'AST(GMT-4)',
47
+ },
48
+ {
49
+ id: 'America/St_Johns',
50
+ value: 'NST(GMT-3:30)',
51
+ meta: 'NST(GMT-3:30)',
52
+ },
53
+ {
54
+ id: 'America/Noronha',
55
+ value: 'FNT(GMT-2)',
56
+ meta: 'FNT(GMT-2)',
57
+ },
58
+ {
59
+ id: 'Asia/Calcutta',
60
+ value: 'IST(GMT+5:30)',
61
+ meta: 'IST(GMT+5:30)',
62
+ },
63
+ {
64
+ id: 'Asia/Kolkata',
65
+ value: 'IST(GMT+5:30)',
66
+ meta: 'IST(GMT+5:30)',
67
+ },
68
+ {
69
+ id: 'Asia/Dubai',
70
+ value: 'GST(GMT+4)',
71
+ meta: 'GST(GMT+4)',
72
+ },
73
+ {
74
+ id: 'Asia/Singapore',
75
+ value: 'SGT(GMT+8)',
76
+ meta: 'SGT(GMT+8)',
77
+ },
78
+ {
79
+ id: 'Pacific/Auckland',
80
+ value: 'NZDT(GMT+13)',
81
+ meta: 'NZDT(GMT+13)',
82
+ },
83
+ {
84
+ id: 'Australia/Adelaide',
85
+ value: 'ACDT(GMT+10:30)',
86
+ meta: 'ACDT(GMT+10:30)',
87
+ },
88
+ {
89
+ id: 'Australia/Perth',
90
+ value: 'AWST(GMT+8)',
91
+ meta: 'AWST(GMT+8)',
92
+ },
93
+ {
94
+ id: 'Australia/Sydney',
95
+ value: 'AEDT(GMT+11)',
96
+ meta: 'AEDT(GMT+11)',
97
+ },
98
+ {
99
+ id: 'Australia/Darwin',
100
+ value: 'ACST(GMT+9:30)',
101
+ meta: 'ACST(GMT+9:30)',
102
+ },
103
+ {
104
+ id: 'Australia/Broken_Hill',
105
+ value: 'ACDT(GMT+10:30)',
106
+ meta: 'ACDT(GMT+10:30)',
107
+ },
108
+ {
109
+ id: 'Australia/Melbourne',
110
+ value: 'AEDT(GMT+11)',
111
+ meta: 'AEDT(GMT+11)',
112
+ },
113
+ {
114
+ id: 'Australia/Brisbane',
115
+ value: 'AEST(GMT+10)',
116
+ meta: 'AEST(GMT+10)',
117
+ },
118
+ {
119
+ id: 'Australia/Hobart',
120
+ value: 'AEDT(GMT+11)',
121
+ meta: 'AEDT(GMT+11)',
122
+ },
123
+ {
124
+ id: 'Europe/London',
125
+ value: 'GMT(GMT+0)',
126
+ meta: 'GMT(GMT+0)',
127
+ },
128
+ {
129
+ id: 'Asia/Muscat',
130
+ value: 'GST(GMT+4)',
131
+ meta: 'GST(GMT+4)',
132
+ },
133
+ {
134
+ id: 'Asia/Kuwait',
135
+ value: 'AST(GMT+3)',
136
+ meta: 'AST(GMT+3)',
137
+ },
138
+ {
139
+ id: 'Asia/Bahrain',
140
+ value: 'AST(GMT+3)',
141
+ meta: 'AST(GMT+3)',
142
+ },
143
+ {
144
+ id: 'Asia/Qatar',
145
+ value: 'AST(GMT+3)',
146
+ meta: 'AST(GMT+3)',
147
+ },
148
+ {
149
+ id: 'Asia/Riyadh',
150
+ value: 'AST(GMT+3)',
151
+ meta: 'AST(GMT+3)',
152
+ },
153
+ ].map(timezone => ({
154
+ ...timezone,
155
+ key: timezone.id,
156
+ label: timezone.meta,
157
+ }));
@@ -0,0 +1,59 @@
1
+ export const getCookie = (name: string, cookie: string = document.cookie): string => {
2
+ if (!cookie) {
3
+ return '';
4
+ }
5
+
6
+ const cookies = cookie.split('; ');
7
+
8
+ for (let i = 0; i < cookies.length; i += 1) {
9
+ if (cookies[i]) {
10
+ const [key, value] = cookies[i].split('=');
11
+
12
+ if (key === name) {
13
+ return value;
14
+ }
15
+ }
16
+ }
17
+
18
+ return '';
19
+ };
20
+
21
+ export function removeCookie(name: string, subdomain?: boolean): void {
22
+ const date = new Date();
23
+
24
+ // Set it expire in -1 days
25
+ date.setTime(date.getTime() + -1 * 24 * 60 * 60 * 1000);
26
+
27
+ // Set it
28
+ document.cookie = `${name}=; expires=${date.toUTCString()}; path=/${
29
+ subdomain ? '; domain=cuemath.com' : ''
30
+ }`;
31
+ }
32
+
33
+ export function createCookie(
34
+ name: string,
35
+ value: string,
36
+ days: number,
37
+ subdomain?: boolean,
38
+ ): void {
39
+ let expires = '';
40
+
41
+ if (days) {
42
+ const date = new Date();
43
+
44
+ date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
45
+ expires = `; expires=${date.toUTCString()}`;
46
+ }
47
+ document.cookie = `${name}=${encodeURIComponent(value)}${expires}; path=/${
48
+ subdomain ? '; domain=cuemath.com' : ''
49
+ }`;
50
+ }
51
+
52
+ export function createCookieWithMidnightExp(name: string, value: string): void {
53
+ const date = new Date();
54
+
55
+ date.setHours(24, 0, 0, 0);
56
+ const expires = `; expires=${date}`;
57
+
58
+ document.cookie = `${name}=${value}${expires}; path=/`;
59
+ }
@@ -0,0 +1,139 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import dayjs from 'dayjs';
3
+ import relativeTime from 'dayjs/plugin/relativeTime';
4
+
5
+ import { timezones } from '../constants/date-time/international-timezones';
6
+
7
+ type Timestamp = number;
8
+
9
+ export interface DateSlots {
10
+ key: number;
11
+ label: string;
12
+ subLabel: string;
13
+ disabled: boolean;
14
+ }
15
+
16
+ export const formatDateTime = (
17
+ dateTime: string | number | Date | dayjs.Dayjs | null | undefined,
18
+ format: string | undefined,
19
+ ) => {
20
+ const momentDate = dayjs(dateTime);
21
+
22
+ return momentDate.format(format);
23
+ };
24
+
25
+ export function getCurrentTimestamp(): number {
26
+ if (!Date.now) {
27
+ Date.now = () => new Date().getTime();
28
+ }
29
+
30
+ return Math.floor(Date.now() / 1000);
31
+ }
32
+
33
+ export function dateTimeByTimezone(timestamp: Timestamp, timezone?: string): string {
34
+ let options = {};
35
+
36
+ if (timezone) {
37
+ options = {
38
+ timeZone: timezone,
39
+ };
40
+ }
41
+
42
+ return new Date(timestamp).toLocaleString('en-US', options);
43
+ }
44
+
45
+ export function dateByTimezone(
46
+ timestamp: number,
47
+ timezone: string,
48
+ format: string,
49
+ ): string {
50
+ const datetime = dateTimeByTimezone(timestamp, timezone);
51
+
52
+ return dayjs(datetime).format(format || 'mm/dd/yyyy');
53
+ }
54
+
55
+ export const dateByTimestamp = (timestamp: Timestamp, format: string): string => {
56
+ const datetime = new Date(timestamp).toLocaleString('en-US');
57
+
58
+ return dayjs(datetime).format(format || 'mm/dd/yyyy');
59
+ };
60
+
61
+ export function convertTimeStampToSeconds(timeStamp: Timestamp): number {
62
+ const demoTimeStamp = timeStamp;
63
+ const currentTimeStamp = getCurrentTimestamp();
64
+
65
+ if (Number.isNaN(demoTimeStamp) || Number.isNaN(currentTimeStamp)) {
66
+ return timeStamp;
67
+ }
68
+
69
+ const demoTimeStampLength = String(demoTimeStamp).length;
70
+ const currentTimeStampLength = String(currentTimeStamp).length;
71
+
72
+ return demoTimeStampLength > currentTimeStampLength ? timeStamp / 1000 : timeStamp;
73
+ }
74
+
75
+ export function formatTimestamp(datetime: Timestamp, format: string | undefined): string {
76
+ const timeStamp = convertTimeStampToSeconds(datetime);
77
+
78
+ return dayjs.unix(timeStamp).format(format);
79
+ }
80
+
81
+ export function getTimezone(): string {
82
+ return Intl?.DateTimeFormat().resolvedOptions().timeZone;
83
+ }
84
+
85
+ export function timeToX(
86
+ datetime: string | number | Date | dayjs.Dayjs | null | undefined,
87
+ ): string {
88
+ dayjs.extend(relativeTime);
89
+
90
+ return dayjs().to(datetime, true);
91
+ }
92
+
93
+ export function getCurrentDatebyTimezone(timezone: string): string {
94
+ let options = {};
95
+
96
+ if (timezone) {
97
+ options = {
98
+ timeZone: timezone,
99
+ };
100
+ }
101
+
102
+ return new Date().toLocaleString('en-US', options);
103
+ }
104
+
105
+ export function getTimeDiff(
106
+ date1: string | number | Date | dayjs.Dayjs | null | undefined,
107
+ date2: string | number | Date | dayjs.Dayjs | null | undefined,
108
+ ): { days: any; hour: any; minute: any; seconds: any; distance: any } {
109
+ const dateTime1 = dayjs(date1);
110
+ const dateTime2 = dayjs(date2);
111
+
112
+ return {
113
+ days: dateTime1.diff(dateTime2, 'days'),
114
+ hour: dateTime1.diff(dateTime2, 'hour'),
115
+ minute: dateTime1.diff(dateTime2, 'minute'),
116
+ seconds: dateTime1.diff(dateTime2, 'seconds'),
117
+ distance: dateTime1.diff(dateTime2),
118
+ };
119
+ }
120
+
121
+ export function getISOTimeString(demoTs: number): string {
122
+ return new Date(demoTs * 1000).toISOString().replace(/-|:|\.\d\d\d/g, '');
123
+ }
124
+
125
+ export function getDateAfterDays(days: number): string {
126
+ return formatDateTime(dayjs().add(days, 'day'), 'D MMM, YYYY').toUpperCase();
127
+ }
128
+
129
+ export const convertedTimezone = (selectedTimezone: string): string => {
130
+ const formattedTimezone = timezones?.find(
131
+ currentTimezone => currentTimezone?.id === selectedTimezone,
132
+ );
133
+
134
+ return formattedTimezone?.value ?? selectedTimezone?.replaceAll('_', ' ');
135
+ };
136
+
137
+ export const convertSecondsToMiliseconds = (seconds: number) => {
138
+ return seconds * 1000;
139
+ };
@@ -0,0 +1,23 @@
1
+ import { TWENTY_FOUR_HOURS_IN_SECONDS } from '../constants/date-time';
2
+ import { getCurrentDatebyTimezone } from '../date-time-helper/index';
3
+
4
+ // if adding any change in this function, then need update at all the places where we are using this function in website and astro
5
+ export const getDates = (
6
+ timezone: string,
7
+ ): Array<{ futureDate: number; disabled: boolean }> => {
8
+ const currentDate = Date.parse(getCurrentDatebyTimezone(timezone)) / 1000;
9
+ const dates = [];
10
+
11
+ const days = 10;
12
+ const buffer = 2;
13
+
14
+ // getting dates by adding 86400 seconds(24 hours)
15
+ for (let i = 0; i < days; i += 1) {
16
+ dates.push({
17
+ futureDate: currentDate + TWENTY_FOUR_HOURS_IN_SECONDS * i,
18
+ disabled: !(i > buffer),
19
+ });
20
+ }
21
+
22
+ return dates;
23
+ };
@@ -0,0 +1,237 @@
1
+ import type {
2
+ SourceDetails,
3
+ SourceDetailsCookie,
4
+ Platform,
5
+ SignupFlow,
6
+ UTMParams,
7
+ Experiments,
8
+ RevenueChannel,
9
+ UTMParamsKeys,
10
+ } from './types';
11
+
12
+ import { createCookie, getCookie, removeCookie } from '../cookie';
13
+
14
+ export * from './utils';
15
+
16
+ const SOURCE_DETAILS_COOKIE = 'source_details';
17
+ const UTM_PARAMS: UTMParamsKeys[] = [
18
+ 'utm_source',
19
+ 'utm_medium',
20
+ 'utm_campaign',
21
+ 'utm_term',
22
+ ];
23
+
24
+ export const readSourceCookie = (): SourceDetailsCookie => {
25
+ const sourceDetails = getCookie(SOURCE_DETAILS_COOKIE);
26
+
27
+ return sourceDetails ? JSON.parse(decodeURIComponent(sourceDetails)) : undefined;
28
+ };
29
+
30
+ const writeSourceCookie = (sourceDetails: SourceDetailsCookie): void => {
31
+ createCookie(SOURCE_DETAILS_COOKIE, JSON.stringify(sourceDetails), 365);
32
+ };
33
+
34
+ export const isSourcePresent = (): boolean => {
35
+ return !!getCookie(SOURCE_DETAILS_COOKIE);
36
+ };
37
+
38
+ const updateSourceCookie = (sourceDetail: Partial<SourceDetailsCookie>): void => {
39
+ if (!isSourcePresent) return;
40
+
41
+ const sourceDetails: SourceDetailsCookie = readSourceCookie();
42
+ const updatedDetails: SourceDetailsCookie = {
43
+ ...sourceDetails,
44
+ ...sourceDetail,
45
+ };
46
+
47
+ writeSourceCookie(updatedDetails);
48
+ };
49
+
50
+ const getRevenueChannel = (platform: Platform, utmSource?: string): RevenueChannel => {
51
+ let revenueChannel: RevenueChannel = 'unknown';
52
+
53
+ // set defaults for WEBSITE and ASTRO
54
+ if (platform === 'website') {
55
+ revenueChannel = 'organic';
56
+ } else if (platform === 'astro') {
57
+ revenueChannel = 'performance';
58
+ }
59
+
60
+ if (utmSource) {
61
+ switch (true) {
62
+ case /^affiliate-/.test(utmSource):
63
+ revenueChannel = 'affiliate';
64
+ break;
65
+ case /^offline-/.test(utmSource):
66
+ revenueChannel = 'offline';
67
+ break;
68
+ case /^referral-/.test(utmSource):
69
+ revenueChannel = 'referral';
70
+ break;
71
+ case /^performance-/.test(utmSource):
72
+ revenueChannel = 'performance';
73
+ break;
74
+ }
75
+ }
76
+
77
+ return revenueChannel;
78
+ };
79
+
80
+ /*
81
+ if Platform = website, then decide based on experiment key
82
+ if Platform = Astro, decide logic once BAU is started
83
+ if Platform = APP, decide logic
84
+ if Platform = chatbot, decide based on chatbot experiment key
85
+ */
86
+ const getFlow = (platform: Platform, experiments?: Experiments): SignupFlow => {
87
+ let flow: SignupFlow = 'regular';
88
+
89
+ if (platform === 'website') {
90
+ if (experiments) {
91
+ const ecnaExp = Object.keys(experiments).find(
92
+ experiment => experiment.indexOf('ecna') !== -1,
93
+ );
94
+
95
+ flow = ecnaExp && experiments[ecnaExp] === 'b' ? 'e-cna' : 'regular';
96
+ }
97
+ }
98
+
99
+ return flow;
100
+ };
101
+
102
+ const getUTMParams = (): Partial<UTMParams> => {
103
+ if (typeof window === undefined) return {};
104
+
105
+ const search = new URLSearchParams(window.location.search);
106
+ const utmParams = UTM_PARAMS.reduce((acc: UTMParams, param) => {
107
+ const utmParam = search.get(param) as string;
108
+
109
+ if (utmParam) {
110
+ acc[param] = utmParam;
111
+ }
112
+
113
+ return acc;
114
+ }, {});
115
+
116
+ return utmParams;
117
+ };
118
+
119
+ const getFirstPage = (): string => {
120
+ if (typeof window === undefined) return '';
121
+
122
+ return window.location.pathname;
123
+ };
124
+
125
+ /* TODO: Align Marketing Team on UTM source convention
126
+ affiliate-<channel>
127
+ performance-<channel>
128
+ organic-<channel>
129
+ offline-<channel>
130
+ */
131
+ const getChannel = (utmSource?: string): string => {
132
+ // TODO: UTM source patter for FB, GOOGLE...
133
+ if (!utmSource) return '';
134
+
135
+ let channel = '';
136
+
137
+ if (utmSource) {
138
+ switch (true) {
139
+ case /^affiliate-/.test(utmSource):
140
+ case /^offline-/.test(utmSource):
141
+ case /^referral-/.test(utmSource):
142
+ case /^performance-/.test(utmSource):
143
+ channel = utmSource.split('-')[1];
144
+ break;
145
+ default:
146
+ break;
147
+ }
148
+ }
149
+
150
+ return channel;
151
+ };
152
+
153
+ /*
154
+ Set Static Source Details of user on Visit of Platform
155
+ */
156
+ export const initSourceDetails = async ({
157
+ platform,
158
+ experiments,
159
+ flow,
160
+ affiliateChannel,
161
+ offlineChannel,
162
+ organicChannel,
163
+ performanceChannel,
164
+ revenueChannel,
165
+ guestId,
166
+ }: SourceDetails): Promise<void> => {
167
+ const utmParams: Partial<UTMParams> = getUTMParams();
168
+ const { utm_source: utmSource } = utmParams;
169
+ const leadChannel = getChannel(utmSource);
170
+
171
+ /*
172
+ source cookie was added in cross subdomain for few days initially,
173
+ which was later changed to subdomain specific. Now to sending older cookie to backend, removing older cookie
174
+ */
175
+ removeCookie(SOURCE_DETAILS_COOKIE, true);
176
+
177
+ revenueChannel = revenueChannel || getRevenueChannel(platform, utmSource);
178
+
179
+ if (utmSource) {
180
+ affiliateChannel =
181
+ revenueChannel === 'affiliate' ? affiliateChannel || leadChannel : undefined;
182
+ offlineChannel =
183
+ revenueChannel === 'offline' ? offlineChannel || leadChannel : undefined;
184
+ organicChannel =
185
+ revenueChannel === 'organic' ? organicChannel || leadChannel : undefined;
186
+ performanceChannel =
187
+ revenueChannel === 'performance' ? performanceChannel || leadChannel : undefined;
188
+ }
189
+
190
+ if (!isSourcePresent()) {
191
+ const sourceDetails: SourceDetailsCookie = {
192
+ platform_channel: platform,
193
+ experiment_dict: experiments,
194
+ utm_params: utmParams,
195
+ flow: flow || getFlow(platform, experiments),
196
+ affiliate_channel: affiliateChannel,
197
+ offline_channel: offlineChannel,
198
+ organic_channel: organicChannel,
199
+ performance_channel: performanceChannel,
200
+ revenue_channel: revenueChannel,
201
+ first_page: getFirstPage(),
202
+ guest_id: guestId,
203
+ };
204
+
205
+ writeSourceCookie(sourceDetails);
206
+ } else {
207
+ let updatedSource: Partial<SourceDetailsCookie> = {
208
+ experiment_dict: experiments,
209
+ flow: flow || getFlow(platform, experiments),
210
+ guest_id: guestId,
211
+ };
212
+
213
+ if (utmSource) {
214
+ updatedSource = {
215
+ ...updatedSource,
216
+ utm_params: utmParams,
217
+ affiliate_channel: affiliateChannel,
218
+ offline_channel: offlineChannel,
219
+ organic_channel: organicChannel,
220
+ performance_channel: performanceChannel,
221
+ revenue_channel: revenueChannel,
222
+ };
223
+ }
224
+
225
+ updateSourceCookie(updatedSource);
226
+ }
227
+ };
228
+
229
+ // Last Page which user visited signup before
230
+ export const setLastPage = async (pagePath: string): Promise<void> => {
231
+ updateSourceCookie({ last_page: pagePath });
232
+ };
233
+
234
+ // set Entry point where user clicked to Signup
235
+ export const setFlowEntryPoint = async (flowEntry: string): Promise<void> => {
236
+ updateSourceCookie({ flow_entry: flowEntry });
237
+ };
@@ -0,0 +1,50 @@
1
+ export type Platform = 'website' | 'app' | 'astro' | 'leap-teacher' | 'leap-admin';
2
+ export type RevenueChannel =
3
+ | 'organic'
4
+ | 'performance'
5
+ | 'affiliate'
6
+ | 'offline'
7
+ | 'referral'
8
+ | 'unknown';
9
+ export type SignupFlow = 'regular' | 'e-cna' | 'e-sales';
10
+ export type Experiments = Record<string, unknown>;
11
+ export type UTMParams = {
12
+ utm_source?: string;
13
+ utm_medium?: string;
14
+ utm_campaign?: string;
15
+ utm_term?: string;
16
+ };
17
+
18
+ export type UTMParamsKeys = keyof UTMParams;
19
+
20
+ export type SourceDetailsCookie = {
21
+ platform_channel: Platform;
22
+ experiment_dict?: Experiments;
23
+ flow?: SignupFlow;
24
+ utm_params?: UTMParams;
25
+ affiliate_channel?: string;
26
+ offline_channel?: string;
27
+ performance_channel?: string;
28
+ revenue_channel: RevenueChannel;
29
+ organic_channel?: string;
30
+ flow_entry?: string;
31
+ first_page?: string;
32
+ last_page?: string;
33
+ guest_id?: string;
34
+ };
35
+
36
+ export type SourceDetails = {
37
+ platform: Platform;
38
+ experiments: Experiments;
39
+ flow?: SignupFlow;
40
+ utmParams?: UTMParams;
41
+ affiliateChannel?: string;
42
+ offlineChannel?: string;
43
+ performanceChannel?: string;
44
+ revenueChannel: RevenueChannel;
45
+ organicChannel?: string;
46
+ flowEntry?: string;
47
+ firstPage?: string;
48
+ lastPage?: string;
49
+ guestId?: string;
50
+ };
@@ -0,0 +1,5 @@
1
+ export const APP_ENV = {
2
+ PRODUCTION: 'production',
3
+ STAGING: 'staging',
4
+ DEVELOPMENT: 'development',
5
+ };
@@ -0,0 +1,2 @@
1
+ export * from './env-mode';
2
+ export * from './server';
@@ -0,0 +1 @@
1
+ export const isServer = typeof window === 'undefined';