@formo/analytics 1.16.3 → 1.16.5

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 (263) hide show
  1. package/dist/cjs/src/FormoAnalytics.d.ts +69 -38
  2. package/dist/cjs/src/FormoAnalytics.d.ts.map +1 -1
  3. package/dist/cjs/src/FormoAnalytics.js +143 -198
  4. package/dist/cjs/src/FormoAnalytics.js.map +1 -1
  5. package/dist/cjs/src/FormoAnalyticsProvider.js +5 -5
  6. package/dist/cjs/src/FormoAnalyticsProvider.js.map +1 -1
  7. package/dist/cjs/src/constants/config.d.ts +1 -1
  8. package/dist/cjs/src/constants/config.d.ts.map +1 -1
  9. package/dist/cjs/src/constants/config.js +1 -1
  10. package/dist/cjs/src/constants/config.js.map +1 -1
  11. package/dist/cjs/src/constants/events.d.ts +14 -5
  12. package/dist/cjs/src/constants/events.d.ts.map +1 -1
  13. package/dist/cjs/src/constants/events.js +20 -12
  14. package/dist/cjs/src/constants/events.js.map +1 -1
  15. package/dist/cjs/src/lib/event/EventFactory.d.ts +22 -54
  16. package/dist/cjs/src/lib/event/EventFactory.d.ts.map +1 -1
  17. package/dist/cjs/src/lib/event/EventFactory.js +187 -116
  18. package/dist/cjs/src/lib/event/EventFactory.js.map +1 -1
  19. package/dist/cjs/src/lib/event/EventManager.d.ts +22 -0
  20. package/dist/cjs/src/lib/event/EventManager.d.ts.map +1 -0
  21. package/dist/cjs/src/lib/event/EventManager.js +48 -0
  22. package/dist/cjs/src/lib/event/EventManager.js.map +1 -0
  23. package/dist/cjs/src/lib/event/constants.d.ts +4 -0
  24. package/dist/cjs/src/lib/event/constants.d.ts.map +1 -0
  25. package/dist/cjs/src/lib/event/constants.js +8 -0
  26. package/dist/cjs/src/lib/event/constants.js.map +1 -0
  27. package/dist/cjs/src/lib/event/index.d.ts +1 -0
  28. package/dist/cjs/src/lib/event/index.d.ts.map +1 -1
  29. package/dist/cjs/src/lib/event/index.js +1 -0
  30. package/dist/cjs/src/lib/event/index.js.map +1 -1
  31. package/dist/cjs/src/lib/event/type.d.ts +5 -3
  32. package/dist/cjs/src/lib/event/type.d.ts.map +1 -1
  33. package/dist/cjs/src/lib/event/utils.d.ts +4 -0
  34. package/dist/cjs/src/lib/event/utils.d.ts.map +1 -0
  35. package/dist/cjs/src/lib/event/utils.js +16 -0
  36. package/dist/cjs/src/lib/event/utils.js.map +1 -0
  37. package/dist/cjs/src/lib/fetch.d.ts +1 -1
  38. package/dist/cjs/src/lib/queue/EventQueue.d.ts +1 -0
  39. package/dist/cjs/src/lib/queue/EventQueue.d.ts.map +1 -1
  40. package/dist/cjs/src/lib/queue/EventQueue.js +22 -14
  41. package/dist/cjs/src/lib/queue/EventQueue.js.map +1 -1
  42. package/dist/cjs/src/lib/ramda/internal/_curry1.d.ts +10 -0
  43. package/dist/cjs/src/lib/ramda/internal/_curry1.d.ts.map +1 -0
  44. package/dist/cjs/src/lib/ramda/internal/_curry1.js +26 -0
  45. package/dist/cjs/src/lib/ramda/internal/_curry1.js.map +1 -0
  46. package/dist/cjs/src/lib/ramda/internal/_curry2.d.ts +10 -0
  47. package/dist/cjs/src/lib/ramda/internal/_curry2.d.ts.map +1 -0
  48. package/dist/cjs/src/lib/ramda/internal/_curry2.js +43 -0
  49. package/dist/cjs/src/lib/ramda/internal/_curry2.js.map +1 -0
  50. package/dist/cjs/src/lib/ramda/internal/_curry3.d.ts +10 -0
  51. package/dist/cjs/src/lib/ramda/internal/_curry3.d.ts.map +1 -0
  52. package/dist/cjs/src/lib/ramda/internal/_curry3.js +74 -0
  53. package/dist/cjs/src/lib/ramda/internal/_curry3.js.map +1 -0
  54. package/dist/cjs/src/lib/ramda/internal/_has.d.ts +2 -0
  55. package/dist/cjs/src/lib/ramda/internal/_has.d.ts.map +1 -0
  56. package/dist/cjs/src/lib/ramda/internal/_has.js +7 -0
  57. package/dist/cjs/src/lib/ramda/internal/_has.js.map +1 -0
  58. package/dist/cjs/src/lib/ramda/internal/_isObject.d.ts +2 -0
  59. package/dist/cjs/src/lib/ramda/internal/_isObject.d.ts.map +1 -0
  60. package/dist/cjs/src/lib/ramda/internal/_isObject.js +7 -0
  61. package/dist/cjs/src/lib/ramda/internal/_isObject.js.map +1 -0
  62. package/dist/cjs/src/lib/ramda/internal/_isPlaceholder.d.ts +2 -0
  63. package/dist/cjs/src/lib/ramda/internal/_isPlaceholder.d.ts.map +1 -0
  64. package/dist/cjs/src/lib/ramda/internal/_isPlaceholder.js +7 -0
  65. package/dist/cjs/src/lib/ramda/internal/_isPlaceholder.js.map +1 -0
  66. package/dist/cjs/src/lib/ramda/mergeDeepRight.d.ts +3 -0
  67. package/dist/cjs/src/lib/ramda/mergeDeepRight.d.ts.map +1 -0
  68. package/dist/cjs/src/lib/ramda/mergeDeepRight.js +14 -0
  69. package/dist/cjs/src/lib/ramda/mergeDeepRight.js.map +1 -0
  70. package/dist/cjs/src/lib/ramda/mergeDeepWithKey.d.ts +3 -0
  71. package/dist/cjs/src/lib/ramda/mergeDeepWithKey.d.ts.map +1 -0
  72. package/dist/cjs/src/lib/ramda/mergeDeepWithKey.js +20 -0
  73. package/dist/cjs/src/lib/ramda/mergeDeepWithKey.js.map +1 -0
  74. package/dist/cjs/src/lib/ramda/mergeWithKey.d.ts +3 -0
  75. package/dist/cjs/src/lib/ramda/mergeWithKey.d.ts.map +1 -0
  76. package/dist/cjs/src/lib/ramda/mergeWithKey.js +26 -0
  77. package/dist/cjs/src/lib/ramda/mergeWithKey.js.map +1 -0
  78. package/dist/cjs/src/lib/storage/native.d.ts +1 -0
  79. package/dist/cjs/src/lib/storage/native.d.ts.map +1 -1
  80. package/dist/cjs/src/lib/storage/native.js +3 -0
  81. package/dist/cjs/src/lib/storage/native.js.map +1 -1
  82. package/dist/cjs/src/lib/version.d.ts +2 -0
  83. package/dist/cjs/src/lib/version.d.ts.map +1 -0
  84. package/dist/cjs/src/lib/version.js +6 -0
  85. package/dist/cjs/src/lib/version.js.map +1 -0
  86. package/dist/cjs/src/types/base.d.ts +1 -0
  87. package/dist/cjs/src/types/base.d.ts.map +1 -1
  88. package/dist/cjs/src/types/events.d.ts +55 -27
  89. package/dist/cjs/src/types/events.d.ts.map +1 -1
  90. package/dist/cjs/src/types/events.js.map +1 -1
  91. package/dist/cjs/src/utils/base.d.ts +1 -1
  92. package/dist/cjs/src/utils/base.d.ts.map +1 -1
  93. package/dist/cjs/src/utils/base.js +2 -2
  94. package/dist/cjs/src/utils/base.js.map +1 -1
  95. package/dist/cjs/src/utils/timestamp.d.ts +8 -0
  96. package/dist/cjs/src/utils/timestamp.d.ts.map +1 -0
  97. package/dist/cjs/src/utils/timestamp.js +12 -0
  98. package/dist/cjs/src/utils/timestamp.js.map +1 -0
  99. package/dist/cjs/src/validators/checks.d.ts +77 -0
  100. package/dist/cjs/src/validators/checks.d.ts.map +1 -0
  101. package/dist/cjs/src/validators/checks.js +141 -0
  102. package/dist/cjs/src/validators/checks.js.map +1 -0
  103. package/dist/cjs/src/validators/index.d.ts +2 -1
  104. package/dist/cjs/src/validators/index.d.ts.map +1 -1
  105. package/dist/cjs/src/validators/index.js +2 -1
  106. package/dist/cjs/src/validators/index.js.map +1 -1
  107. package/dist/cjs/src/validators/network.d.ts +2 -0
  108. package/dist/cjs/src/validators/network.d.ts.map +1 -0
  109. package/dist/cjs/src/validators/network.js +31 -0
  110. package/dist/cjs/src/validators/network.js.map +1 -0
  111. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  112. package/dist/esm/src/FormoAnalytics.d.ts +69 -38
  113. package/dist/esm/src/FormoAnalytics.d.ts.map +1 -1
  114. package/dist/esm/src/FormoAnalytics.js +146 -201
  115. package/dist/esm/src/FormoAnalytics.js.map +1 -1
  116. package/dist/esm/src/FormoAnalyticsProvider.js +5 -5
  117. package/dist/esm/src/FormoAnalyticsProvider.js.map +1 -1
  118. package/dist/esm/src/constants/config.d.ts +1 -1
  119. package/dist/esm/src/constants/config.d.ts.map +1 -1
  120. package/dist/esm/src/constants/config.js +1 -1
  121. package/dist/esm/src/constants/config.js.map +1 -1
  122. package/dist/esm/src/constants/events.d.ts +14 -5
  123. package/dist/esm/src/constants/events.d.ts.map +1 -1
  124. package/dist/esm/src/constants/events.js +19 -11
  125. package/dist/esm/src/constants/events.js.map +1 -1
  126. package/dist/esm/src/lib/event/EventFactory.d.ts +22 -54
  127. package/dist/esm/src/lib/event/EventFactory.d.ts.map +1 -1
  128. package/dist/esm/src/lib/event/EventFactory.js +185 -117
  129. package/dist/esm/src/lib/event/EventFactory.js.map +1 -1
  130. package/dist/esm/src/lib/event/EventManager.d.ts +22 -0
  131. package/dist/esm/src/lib/event/EventManager.d.ts.map +1 -0
  132. package/dist/esm/src/lib/event/EventManager.js +45 -0
  133. package/dist/esm/src/lib/event/EventManager.js.map +1 -0
  134. package/dist/esm/src/lib/event/constants.d.ts +4 -0
  135. package/dist/esm/src/lib/event/constants.d.ts.map +1 -0
  136. package/dist/esm/src/lib/event/constants.js +4 -0
  137. package/dist/esm/src/lib/event/constants.js.map +1 -0
  138. package/dist/esm/src/lib/event/index.d.ts +1 -0
  139. package/dist/esm/src/lib/event/index.d.ts.map +1 -1
  140. package/dist/esm/src/lib/event/index.js +1 -0
  141. package/dist/esm/src/lib/event/index.js.map +1 -1
  142. package/dist/esm/src/lib/event/type.d.ts +5 -3
  143. package/dist/esm/src/lib/event/type.d.ts.map +1 -1
  144. package/dist/esm/src/lib/event/utils.d.ts +4 -0
  145. package/dist/esm/src/lib/event/utils.d.ts.map +1 -0
  146. package/dist/esm/src/lib/event/utils.js +13 -0
  147. package/dist/esm/src/lib/event/utils.js.map +1 -0
  148. package/dist/esm/src/lib/queue/EventQueue.d.ts +1 -0
  149. package/dist/esm/src/lib/queue/EventQueue.d.ts.map +1 -1
  150. package/dist/esm/src/lib/queue/EventQueue.js +21 -13
  151. package/dist/esm/src/lib/queue/EventQueue.js.map +1 -1
  152. package/dist/esm/src/lib/ramda/internal/_curry1.d.ts +10 -0
  153. package/dist/esm/src/lib/ramda/internal/_curry1.d.ts.map +1 -0
  154. package/dist/esm/src/lib/ramda/internal/_curry1.js +20 -0
  155. package/dist/esm/src/lib/ramda/internal/_curry1.js.map +1 -0
  156. package/dist/esm/src/lib/ramda/internal/_curry2.d.ts +10 -0
  157. package/dist/esm/src/lib/ramda/internal/_curry2.d.ts.map +1 -0
  158. package/dist/esm/src/lib/ramda/internal/_curry2.js +37 -0
  159. package/dist/esm/src/lib/ramda/internal/_curry2.js.map +1 -0
  160. package/dist/esm/src/lib/ramda/internal/_curry3.d.ts +10 -0
  161. package/dist/esm/src/lib/ramda/internal/_curry3.d.ts.map +1 -0
  162. package/dist/esm/src/lib/ramda/internal/_curry3.js +68 -0
  163. package/dist/esm/src/lib/ramda/internal/_curry3.js.map +1 -0
  164. package/dist/esm/src/lib/ramda/internal/_has.d.ts +2 -0
  165. package/dist/esm/src/lib/ramda/internal/_has.d.ts.map +1 -0
  166. package/dist/esm/src/lib/ramda/internal/_has.js +4 -0
  167. package/dist/esm/src/lib/ramda/internal/_has.js.map +1 -0
  168. package/dist/esm/src/lib/ramda/internal/_isObject.d.ts +2 -0
  169. package/dist/esm/src/lib/ramda/internal/_isObject.d.ts.map +1 -0
  170. package/dist/esm/src/lib/ramda/internal/_isObject.js +4 -0
  171. package/dist/esm/src/lib/ramda/internal/_isObject.js.map +1 -0
  172. package/dist/esm/src/lib/ramda/internal/_isPlaceholder.d.ts +2 -0
  173. package/dist/esm/src/lib/ramda/internal/_isPlaceholder.d.ts.map +1 -0
  174. package/dist/esm/src/lib/ramda/internal/_isPlaceholder.js +4 -0
  175. package/dist/esm/src/lib/ramda/internal/_isPlaceholder.js.map +1 -0
  176. package/dist/esm/src/lib/ramda/mergeDeepRight.d.ts +3 -0
  177. package/dist/esm/src/lib/ramda/mergeDeepRight.d.ts.map +1 -0
  178. package/dist/esm/src/lib/ramda/mergeDeepRight.js +9 -0
  179. package/dist/esm/src/lib/ramda/mergeDeepRight.js.map +1 -0
  180. package/dist/esm/src/lib/ramda/mergeDeepWithKey.d.ts +3 -0
  181. package/dist/esm/src/lib/ramda/mergeDeepWithKey.d.ts.map +1 -0
  182. package/dist/esm/src/lib/ramda/mergeDeepWithKey.js +15 -0
  183. package/dist/esm/src/lib/ramda/mergeDeepWithKey.js.map +1 -0
  184. package/dist/esm/src/lib/ramda/mergeWithKey.d.ts +3 -0
  185. package/dist/esm/src/lib/ramda/mergeWithKey.d.ts.map +1 -0
  186. package/dist/esm/src/lib/ramda/mergeWithKey.js +21 -0
  187. package/dist/esm/src/lib/ramda/mergeWithKey.js.map +1 -0
  188. package/dist/esm/src/lib/storage/native.d.ts +1 -0
  189. package/dist/esm/src/lib/storage/native.d.ts.map +1 -1
  190. package/dist/esm/src/lib/storage/native.js +3 -0
  191. package/dist/esm/src/lib/storage/native.js.map +1 -1
  192. package/dist/esm/src/lib/version.d.ts +2 -0
  193. package/dist/esm/src/lib/version.d.ts.map +1 -0
  194. package/dist/esm/src/lib/version.js +3 -0
  195. package/dist/esm/src/lib/version.js.map +1 -0
  196. package/dist/esm/src/types/base.d.ts +1 -0
  197. package/dist/esm/src/types/base.d.ts.map +1 -1
  198. package/dist/esm/src/types/events.d.ts +55 -27
  199. package/dist/esm/src/types/events.d.ts.map +1 -1
  200. package/dist/esm/src/types/events.js.map +1 -1
  201. package/dist/esm/src/utils/base.d.ts +1 -1
  202. package/dist/esm/src/utils/base.d.ts.map +1 -1
  203. package/dist/esm/src/utils/base.js +2 -2
  204. package/dist/esm/src/utils/base.js.map +1 -1
  205. package/dist/esm/src/utils/timestamp.d.ts +8 -0
  206. package/dist/esm/src/utils/timestamp.d.ts.map +1 -0
  207. package/dist/esm/src/utils/timestamp.js +8 -0
  208. package/dist/esm/src/utils/timestamp.js.map +1 -0
  209. package/dist/esm/src/validators/checks.d.ts +77 -0
  210. package/dist/esm/src/validators/checks.d.ts.map +1 -0
  211. package/dist/esm/src/validators/checks.js +119 -0
  212. package/dist/esm/src/validators/checks.js.map +1 -0
  213. package/dist/esm/src/validators/index.d.ts +2 -1
  214. package/dist/esm/src/validators/index.d.ts.map +1 -1
  215. package/dist/esm/src/validators/index.js +2 -1
  216. package/dist/esm/src/validators/index.js.map +1 -1
  217. package/dist/esm/src/validators/network.d.ts +2 -0
  218. package/dist/esm/src/validators/network.d.ts.map +1 -0
  219. package/dist/esm/src/validators/network.js +28 -0
  220. package/dist/esm/src/validators/network.js.map +1 -0
  221. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  222. package/dist/index.umd.min.js +1 -1
  223. package/dist/index.umd.min.js.map +1 -1
  224. package/package.json +3 -3
  225. package/src/FormoAnalytics.ts +380 -242
  226. package/src/FormoAnalyticsProvider.tsx +5 -5
  227. package/src/constants/config.ts +1 -1
  228. package/src/constants/events.ts +15 -4
  229. package/src/lib/event/EventFactory.ts +358 -162
  230. package/src/lib/event/EventManager.ts +39 -0
  231. package/src/lib/event/constants.ts +4 -0
  232. package/src/lib/event/index.ts +1 -0
  233. package/src/lib/event/type.ts +6 -8
  234. package/src/lib/event/utils.ts +15 -0
  235. package/src/lib/queue/EventQueue.ts +23 -11
  236. package/src/lib/ramda/internal/_curry1.ts +19 -0
  237. package/src/lib/ramda/internal/_curry2.ts +37 -0
  238. package/src/lib/ramda/internal/_curry3.ts +68 -0
  239. package/src/lib/ramda/internal/_has.ts +3 -0
  240. package/src/lib/ramda/internal/_isObject.ts +3 -0
  241. package/src/lib/ramda/internal/_isPlaceholder.ts +5 -0
  242. package/src/lib/ramda/mergeDeepRight.ts +13 -0
  243. package/src/lib/ramda/mergeDeepWithKey.ts +22 -0
  244. package/src/lib/ramda/mergeWithKey.ts +28 -0
  245. package/src/lib/storage/native.ts +4 -0
  246. package/src/lib/version.ts +2 -0
  247. package/src/types/base.ts +1 -0
  248. package/src/types/events.ts +93 -58
  249. package/src/utils/base.ts +2 -2
  250. package/src/utils/timestamp.ts +9 -0
  251. package/src/validators/checks.ts +160 -0
  252. package/src/validators/index.ts +2 -1
  253. package/src/validators/network.ts +34 -0
  254. package/tsconfig.json +1 -1
  255. package/dist/cjs/src/validators/type-check.d.ts +0 -14
  256. package/dist/cjs/src/validators/type-check.d.ts.map +0 -1
  257. package/dist/cjs/src/validators/type-check.js +0 -61
  258. package/dist/cjs/src/validators/type-check.js.map +0 -1
  259. package/dist/esm/src/validators/type-check.d.ts +0 -14
  260. package/dist/esm/src/validators/type-check.d.ts.map +0 -1
  261. package/dist/esm/src/validators/type-check.js +0 -46
  262. package/dist/esm/src/validators/type-check.js.map +0 -1
  263. package/src/validators/type-check.ts +0 -61
@@ -8,16 +8,16 @@ export const FormoAnalyticsContext = createContext<FormoAnalytics | undefined>(
8
8
  );
9
9
 
10
10
  export const FormoAnalyticsProvider = (props: FormoAnalyticsProviderProps) => {
11
- const { writeKey, disabled, children } = props;
11
+ const { writeKey, disabled = false, children } = props;
12
12
 
13
13
  // Keep the app running without analytics if no Write Key is provided or disabled
14
14
  if (!writeKey) {
15
- logger.error("FormoAnalyticsProvider: No Write Key provided");
15
+ console.error("FormoAnalyticsProvider: No Write Key provided");
16
16
  return children;
17
17
  }
18
18
 
19
19
  if (disabled) {
20
- logger.warn("FormoAnalytics is disabled");
20
+ console.warn("FormoAnalytics is disabled");
21
21
  return children;
22
22
  }
23
23
 
@@ -36,9 +36,9 @@ const InitializedAnalytics = ({
36
36
  try {
37
37
  const sdkInstance = await FormoAnalytics.init(writeKey, options);
38
38
  setSdk(sdkInstance);
39
- logger.log("FormoAnalytics SDK initialized successfully");
39
+ console.log("FormoAnalytics SDK initialized successfully");
40
40
  } catch (error) {
41
- logger.error("Failed to initialize FormoAnalytics SDK", error);
41
+ console.error("Failed to initialize FormoAnalytics SDK", error);
42
42
  }
43
43
  };
44
44
 
@@ -1,5 +1,5 @@
1
1
  export const EVENTS_API_HOST = "https://events.formo.so";
2
- export const EVENTS_API_URL = `${EVENTS_API_HOST}/events`;
2
+ export const EVENTS_API_URL = `${EVENTS_API_HOST}/v0/raw_events`;
3
3
  export const USER_API_URL = `${EVENTS_API_HOST}/user`;
4
4
 
5
5
  export const EVENTS_API_REQUEST_HEADER = (writeKey: string) => ({
@@ -1,10 +1,21 @@
1
- export enum Event {
2
- PAGE = "page_hit",
1
+ export enum EventType {
2
+ PAGE = "page",
3
3
  IDENTIFY = "identify",
4
- DETECT_WALLET = "detect_wallet",
4
+ DETECT = "detect",
5
5
  CONNECT = "connect",
6
6
  DISCONNECT = "disconnect",
7
- CHAIN_CHANGED = "chain_changed",
7
+ CHAIN = "chain",
8
8
  SIGNATURE = "signature",
9
9
  TRANSACTION = "transaction",
10
+ TRACK = "track",
10
11
  }
12
+
13
+ export enum EventChannel {
14
+ WEB = "web",
15
+ MOBILE = "mobile",
16
+ SERVER = "server",
17
+ SOURCE = "source",
18
+ }
19
+
20
+ export type TEventType = Lowercase<EventType>;
21
+ export type TEventChannel = Lowercase<EventChannel>;
@@ -1,27 +1,51 @@
1
- import { UUID } from "crypto";
2
1
  import { COUNTRY_LIST } from "../../constants";
3
2
  import {
4
3
  Address,
5
4
  APIEvent,
6
5
  ChainID,
6
+ IFormoEvent,
7
+ IFormoEventContext,
8
+ IFormoEventProperties,
9
+ Nullable,
7
10
  SignatureStatus,
8
11
  TransactionStatus,
12
+ UTMParameters,
9
13
  } from "../../types";
14
+ import {
15
+ generateNativeUUID,
16
+ toChecksumAddress,
17
+ toSnakeCase,
18
+ } from "../../utils";
19
+ import { getCurrentTimeFormatted } from "../../utils/timestamp";
20
+ import { isUndefined } from "../../validators";
10
21
  import { logger } from "../logger";
22
+ import mergeDeepRight from "../ramda/mergeDeepRight";
23
+ import { local } from "../storage";
24
+ import { version } from "../version";
25
+ import { CHANNEL, VERSION } from "./constants";
11
26
  import { IEventFactory } from "./type";
12
- import { toChecksumAddress, toSnakeCase } from "../../utils";
27
+ import { generateAnonymousId } from "./utils";
13
28
 
14
29
  class EventFactory implements IEventFactory {
15
30
  constructor() {}
16
31
 
32
+ private getTimezone(): string {
33
+ try {
34
+ return Intl.DateTimeFormat().resolvedOptions().timeZone;
35
+ } catch (error) {
36
+ logger.error("Error resolving timezone:", error);
37
+ return "";
38
+ }
39
+ }
40
+
17
41
  private getLocation(): string | undefined {
18
42
  try {
19
- const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
43
+ const timezone = this.getTimezone();
20
44
  if (timezone in COUNTRY_LIST)
21
45
  return COUNTRY_LIST[timezone as keyof typeof COUNTRY_LIST];
22
46
  return timezone;
23
47
  } catch (error) {
24
- logger.error("Error resolving timezone:", error);
48
+ logger.error("Error resolving location:", error);
25
49
  return "";
26
50
  }
27
51
  }
@@ -39,95 +63,236 @@ class EventFactory implements IEventFactory {
39
63
  }
40
64
  }
41
65
 
42
- private buildCommonProperties(
43
- anonymous_id: UUID,
44
- user_id: string | null,
45
- address: string | null,
46
- action: string
47
- ) {
48
- // common properties
49
- return {
50
- anonymous_id,
51
- user_id,
52
- address: address && toChecksumAddress(address),
53
- timestamp: new Date().toISOString(),
54
- action,
55
- version: "1",
56
- };
66
+ private getLibraryVersion(): string {
67
+ return version;
57
68
  }
58
69
 
59
- private buildCommonPayload() {
60
- const url = new URL(window.location.href);
70
+ private extractUTMParameters = (url: string): UTMParameters => {
71
+ const result: UTMParameters = {};
72
+ try {
73
+ const urlObj = new URL(url);
74
+ const UTM_PREFIX = "utm_";
75
+ urlObj.searchParams.forEach((value, sParam) => {
76
+ if (sParam.startsWith(UTM_PREFIX)) {
77
+ result[sParam] = value.trim() || "";
78
+ }
79
+ });
80
+ } catch (error) {}
81
+ return result;
82
+ };
61
83
 
62
- const location = this.getLocation();
84
+ // Contextual fields that are automatically collected and populated by the Formo SDK
85
+ private generateContext(context?: IFormoEventContext): IFormoEventContext {
86
+ const url = new URL(globalThis.location.href);
87
+ const params = new URLSearchParams(url.search);
88
+ const path = globalThis.location.pathname;
63
89
  const language = this.getLanguage();
90
+ const timezone = this.getTimezone();
91
+ const location = this.getLocation();
92
+ const library_version = this.getLibraryVersion();
64
93
 
65
- // common properties
66
- return {
67
- "user-agent": window.navigator.userAgent,
94
+ // contextual properties
95
+ const defaultContext = {
96
+ user_agent: globalThis.navigator.userAgent,
68
97
  href: url.href,
69
98
  locale: language,
99
+ timezone,
70
100
  location,
101
+ referrer: document.referrer,
102
+ ...this.extractUTMParameters(globalThis.location.href),
103
+ ref: params.get("ref")?.trim() || "",
104
+ page_path: path,
105
+ page_title: document.title,
106
+ page_url: url.href,
107
+ library_name: "Formo Web SDK",
108
+ library_version,
71
109
  };
110
+
111
+ const mergedContext = mergeDeepRight(
112
+ defaultContext,
113
+ context || {}
114
+ ) as IFormoEventContext;
115
+
116
+ return mergedContext;
72
117
  }
73
118
 
74
- generatePageEvent() {
75
- const url = new URL(window.location.href);
76
- const params = new URLSearchParams(url.search);
77
- const pathname = window.location.pathname;
78
- const hash = window.location.hash;
119
+ /**
120
+ * Add any missing default page properties using values from options and defaults
121
+ * @param properties Input page properties
122
+ * @param options API options
123
+ */
124
+ private getPageProperties = (
125
+ properties: IFormoEventProperties
126
+ ): IFormoEventProperties => {
127
+ const pageProps = properties;
79
128
 
80
- return {
81
- pathname: pathname || url.pathname,
82
- hash: hash || url.hash,
83
- referrer: document.referrer,
84
- utm_source: params.get("utm_source")?.trim() || "",
85
- utm_medium: params.get("utm_medium")?.trim() || "",
86
- utm_campaign: params.get("utm_campaign")?.trim() || "",
87
- utm_content: params.get("utm_content")?.trim() || "",
88
- utm_term: params.get("utm_term")?.trim() || "",
89
- ref: params.get("ref")?.trim() || "",
129
+ if (isUndefined(pageProps.url)) {
130
+ pageProps.url = new URL(globalThis.location.href).href;
131
+ }
132
+
133
+ if (isUndefined(pageProps.path)) {
134
+ pageProps.path = globalThis.location.pathname;
135
+ }
136
+
137
+ if (isUndefined(pageProps.hash)) {
138
+ pageProps.hash = globalThis.location.hash;
139
+ }
140
+
141
+ return pageProps;
142
+ };
143
+
144
+ private getEnrichedEvent = (
145
+ formoEvent: Partial<IFormoEvent>,
146
+ context?: IFormoEventContext
147
+ ): IFormoEvent => {
148
+ const commonEventData = {
149
+ context: this.generateContext(context),
150
+ original_timestamp: getCurrentTimeFormatted(),
151
+ user_id: formoEvent.user_id,
152
+ type: formoEvent.type,
153
+ channel: CHANNEL,
154
+ version: VERSION,
155
+ } as Partial<IFormoEvent>;
156
+
157
+ if (!local.isAvailable()) {
158
+ commonEventData.anonymous_id = generateNativeUUID();
159
+ } else {
160
+ commonEventData.anonymous_id = generateAnonymousId();
161
+ }
162
+
163
+ if (formoEvent.address) {
164
+ commonEventData.address = toChecksumAddress(formoEvent.address);
165
+ } else {
166
+ commonEventData.address = formoEvent.address;
167
+ }
168
+
169
+ const processedEvent = mergeDeepRight(
170
+ formoEvent,
171
+ commonEventData
172
+ ) as IFormoEvent;
173
+
174
+ if (processedEvent.event === undefined) {
175
+ processedEvent.event = null;
176
+ }
177
+
178
+ if (processedEvent.properties === undefined) {
179
+ processedEvent.properties = null;
180
+ }
181
+
182
+ return toSnakeCase(processedEvent);
183
+ };
184
+
185
+ generatePageEvent(
186
+ category?: string,
187
+ name?: string,
188
+ properties?: IFormoEventProperties,
189
+ context?: IFormoEventContext
190
+ ): IFormoEvent {
191
+ let props = properties ?? {};
192
+ props.category = category;
193
+ props.name = name;
194
+ props = this.getPageProperties(props);
195
+
196
+ const pageEvent: Partial<IFormoEvent> = {
197
+ properties: props,
198
+ type: "page",
90
199
  };
200
+
201
+ return this.getEnrichedEvent(pageEvent, context);
91
202
  }
92
203
 
93
- generateConnectEvent(chainId: ChainID, address: Address) {
94
- return {
95
- chainId,
96
- address,
204
+ generateDetectWalletEvent(
205
+ providerName: string,
206
+ rdns: string,
207
+ properties?: IFormoEventProperties,
208
+ context?: IFormoEventContext
209
+ ) {
210
+ const detectEvent: Partial<IFormoEvent> = {
211
+ properties: {
212
+ providerName,
213
+ rdns,
214
+ ...properties,
215
+ },
216
+ type: "detect",
97
217
  };
218
+
219
+ return this.getEnrichedEvent(detectEvent, context);
98
220
  }
99
221
 
100
- generateDisconnectEvent(chainId: ChainID, address: Address) {
101
- return {
102
- chainId,
222
+ generateIdentifyEvent(
223
+ providerName: string,
224
+ rdns: string,
225
+ address: Nullable<Address>,
226
+ userId?: Nullable<string>,
227
+ properties?: IFormoEventProperties,
228
+ context?: IFormoEventContext
229
+ ) {
230
+ const identifyEvent: Partial<IFormoEvent> = {
231
+ properties: {
232
+ providerName,
233
+ rdns,
234
+ ...properties,
235
+ },
236
+ user_id: userId,
103
237
  address,
238
+ type: "identify",
104
239
  };
240
+
241
+ return this.getEnrichedEvent(identifyEvent, context);
105
242
  }
106
243
 
107
- generateDetectWalletEvent(providerName: string, rdns: string) {
108
- return {
109
- providerName,
110
- rdns,
244
+ generateConnectEvent(
245
+ chainId: ChainID,
246
+ address: Address,
247
+ properties?: IFormoEventProperties,
248
+ context?: IFormoEventContext
249
+ ) {
250
+ const connectEvent: Partial<IFormoEvent> = {
251
+ properties: {
252
+ chainId,
253
+ ...properties,
254
+ },
255
+ address,
256
+ type: "connect",
111
257
  };
258
+
259
+ return this.getEnrichedEvent(connectEvent, context);
112
260
  }
113
261
 
114
- generateIdentifyEvent(
115
- address: Address | null,
116
- providerName: string,
117
- rdns: string
262
+ generateDisconnectEvent(
263
+ chainId: ChainID,
264
+ address: Address,
265
+ properties?: IFormoEventProperties,
266
+ context?: IFormoEventContext
118
267
  ) {
119
- return {
268
+ const disconnectEvent: Partial<IFormoEvent> = {
269
+ properties: {
270
+ chainId,
271
+ ...properties,
272
+ },
120
273
  address,
121
- providerName,
122
- rdns,
274
+ type: "disconnect",
123
275
  };
276
+
277
+ return this.getEnrichedEvent(disconnectEvent, context);
124
278
  }
125
279
 
126
- generateChainChangedEvent(chainId: ChainID, address: Address) {
127
- return {
128
- chainId,
280
+ generateChainChangedEvent(
281
+ chainId: ChainID,
282
+ address: Address,
283
+ properties?: IFormoEventProperties,
284
+ context?: IFormoEventContext
285
+ ) {
286
+ const chainEvent: Partial<IFormoEvent> = {
287
+ properties: {
288
+ chainId,
289
+ ...properties,
290
+ },
129
291
  address,
292
+ type: "chain",
130
293
  };
294
+
295
+ return this.getEnrichedEvent(chainEvent, context);
131
296
  }
132
297
 
133
298
  generateSignatureEvent(
@@ -135,15 +300,23 @@ class EventFactory implements IEventFactory {
135
300
  chainId: ChainID,
136
301
  address: Address,
137
302
  message: string,
138
- signatureHash: string
303
+ signatureHash: string,
304
+ properties?: IFormoEventProperties,
305
+ context?: IFormoEventContext
139
306
  ) {
140
- return {
141
- status,
142
- chainId,
307
+ const signatureEvent: Partial<IFormoEvent> = {
308
+ properties: {
309
+ status,
310
+ chainId,
311
+ message,
312
+ signatureHash,
313
+ ...properties,
314
+ },
143
315
  address,
144
- message,
145
- signatureHash,
316
+ type: "signature",
146
317
  };
318
+
319
+ return this.getEnrichedEvent(signatureEvent, context);
147
320
  }
148
321
 
149
322
  generateTransactionEvent(
@@ -153,110 +326,133 @@ class EventFactory implements IEventFactory {
153
326
  data: string,
154
327
  to: string,
155
328
  value: string,
156
- transactionHash: string
329
+ transactionHash: string,
330
+ properties?: IFormoEventProperties,
331
+ context?: IFormoEventContext
157
332
  ) {
158
- return {
159
- status,
160
- chainId,
333
+ const transactionEvent: Partial<IFormoEvent> = {
334
+ properties: {
335
+ status,
336
+ chainId,
337
+ data,
338
+ to,
339
+ value,
340
+ transactionHash,
341
+ ...properties,
342
+ },
161
343
  address,
162
- data,
163
- to,
164
- value,
165
- transactionHash,
344
+ type: "transaction",
166
345
  };
167
- }
168
346
 
169
- generateCustomEvent(args: any) {
170
- if (typeof args !== "object") {
171
- logger.warn("Invalid event data");
172
- return {};
173
- }
174
- const { action, ...rest } = args;
347
+ return this.getEnrichedEvent(transactionEvent, context);
348
+ }
175
349
 
176
- return {
177
- ...rest,
350
+ generateTrackEvent(
351
+ event: string,
352
+ properties?: IFormoEventProperties,
353
+ context?: IFormoEventContext
354
+ ) {
355
+ const transactionEvent: Partial<IFormoEvent> = {
356
+ properties,
357
+ event,
358
+ type: "track",
178
359
  };
360
+
361
+ return this.getEnrichedEvent(transactionEvent, context);
179
362
  }
180
363
 
181
- create(
182
- anonymous_id: UUID,
183
- user_id: string | null,
184
- address: string | null,
185
- event: APIEvent
186
- ) {
187
- const commonProperties = this.buildCommonProperties(
188
- anonymous_id,
189
- user_id,
190
- address,
191
- event.action
192
- );
193
- const payload = this.buildCommonPayload();
194
- let eventSpecificPayload = this.generateCustomEvent(event);
195
- if (event.action === "page_hit") {
196
- eventSpecificPayload = this.generatePageEvent();
197
- }
198
- if (event.action === "connect") {
199
- eventSpecificPayload = this.generateConnectEvent(
200
- event.chainId,
201
- event.address
202
- );
203
- }
204
- if (event.action === "disconnect") {
205
- eventSpecificPayload = this.generateDisconnectEvent(
206
- event.chainId,
207
- event.address
208
- );
209
- }
210
- if (event.action === "detect_wallet") {
211
- eventSpecificPayload = this.generateDetectWalletEvent(
212
- event.providerName,
213
- event.rdns
214
- );
215
- }
216
- if (event.action === "identify") {
217
- eventSpecificPayload = this.generateIdentifyEvent(
218
- event.address,
219
- event.providerName,
220
- event.rdns
221
- );
222
- }
223
- if (event.action === "chain_changed") {
224
- eventSpecificPayload = this.generateChainChangedEvent(
225
- event.chainId,
226
- event.address
227
- );
228
- }
229
- if (event.action === "signature") {
230
- eventSpecificPayload = this.generateSignatureEvent(
231
- event.status,
232
- event.chainId,
233
- event.address,
234
- event.message,
235
- event.signatureHash
236
- );
237
- }
238
- if (event.action === "transaction") {
239
- eventSpecificPayload = this.generateTransactionEvent(
240
- event.status,
241
- event.chainId,
242
- event.address,
243
- event.data,
244
- event.to,
245
- event.value,
246
- event.transactionHash
247
- );
248
- }
364
+ // Returns an event with type, context, properties, and common properties
365
+ create(event: APIEvent, address?: Address, userId?: string): IFormoEvent {
366
+ let formoEvent: Partial<IFormoEvent> = {};
249
367
 
250
- return toSnakeCase(
251
- {
252
- ...commonProperties,
253
- payload: {
254
- ...payload,
255
- ...eventSpecificPayload,
256
- },
257
- },
258
- ["user-agent"]
259
- );
368
+ formoEvent.address = address || null;
369
+ formoEvent.user_id = userId || null;
370
+
371
+ switch (event.type) {
372
+ case "page":
373
+ formoEvent = this.generatePageEvent(
374
+ event.category,
375
+ event.name,
376
+ event.properties,
377
+ event.context
378
+ );
379
+ break;
380
+ case "detect":
381
+ formoEvent = this.generateDetectWalletEvent(
382
+ event.providerName,
383
+ event.rdns,
384
+ event.properties,
385
+ event.context
386
+ );
387
+ break;
388
+ case "identify":
389
+ formoEvent = this.generateIdentifyEvent(
390
+ event.providerName,
391
+ event.rdns,
392
+ event.address,
393
+ event.userId,
394
+ event.properties,
395
+ event.context
396
+ );
397
+ break;
398
+ case "chain":
399
+ formoEvent = this.generateChainChangedEvent(
400
+ event.chainId,
401
+ event.address,
402
+ event.properties,
403
+ event.context
404
+ );
405
+ break;
406
+ case "connect":
407
+ formoEvent = this.generateConnectEvent(
408
+ event.chainId,
409
+ event.address,
410
+ event.properties,
411
+ event.context
412
+ );
413
+ break;
414
+ case "disconnect":
415
+ formoEvent = this.generateDisconnectEvent(
416
+ event.chainId,
417
+ event.address,
418
+ event.properties,
419
+ event.context
420
+ );
421
+ break;
422
+ case "signature":
423
+ formoEvent = this.generateSignatureEvent(
424
+ event.status,
425
+ event.chainId,
426
+ event.address,
427
+ event.message,
428
+ event.signatureHash,
429
+ event.properties,
430
+ event.context
431
+ );
432
+ break;
433
+ case "transaction":
434
+ formoEvent = this.generateTransactionEvent(
435
+ event.status,
436
+ event.chainId,
437
+ event.address,
438
+ event.data,
439
+ event.to,
440
+ event.value,
441
+ event.transactionHash,
442
+ event.properties,
443
+ event.context
444
+ );
445
+ break;
446
+ case "track":
447
+ default:
448
+ formoEvent = this.generateTrackEvent(
449
+ event.event,
450
+ event.properties,
451
+ event.context
452
+ );
453
+ break;
454
+ }
455
+ return formoEvent as IFormoEvent;
260
456
  }
261
457
  }
262
458