@formo/analytics 1.16.4 → 1.16.6

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 (254) 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 +20 -12
  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 +1 -1
  104. package/dist/cjs/src/validators/index.d.ts.map +1 -1
  105. package/dist/cjs/src/validators/index.js +1 -1
  106. package/dist/cjs/src/validators/index.js.map +1 -1
  107. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  108. package/dist/esm/src/FormoAnalytics.d.ts +69 -38
  109. package/dist/esm/src/FormoAnalytics.d.ts.map +1 -1
  110. package/dist/esm/src/FormoAnalytics.js +146 -201
  111. package/dist/esm/src/FormoAnalytics.js.map +1 -1
  112. package/dist/esm/src/FormoAnalyticsProvider.js +5 -5
  113. package/dist/esm/src/FormoAnalyticsProvider.js.map +1 -1
  114. package/dist/esm/src/constants/config.d.ts +1 -1
  115. package/dist/esm/src/constants/config.d.ts.map +1 -1
  116. package/dist/esm/src/constants/config.js +1 -1
  117. package/dist/esm/src/constants/config.js.map +1 -1
  118. package/dist/esm/src/constants/events.d.ts +14 -5
  119. package/dist/esm/src/constants/events.d.ts.map +1 -1
  120. package/dist/esm/src/constants/events.js +19 -11
  121. package/dist/esm/src/constants/events.js.map +1 -1
  122. package/dist/esm/src/lib/event/EventFactory.d.ts +22 -54
  123. package/dist/esm/src/lib/event/EventFactory.d.ts.map +1 -1
  124. package/dist/esm/src/lib/event/EventFactory.js +185 -117
  125. package/dist/esm/src/lib/event/EventFactory.js.map +1 -1
  126. package/dist/esm/src/lib/event/EventManager.d.ts +22 -0
  127. package/dist/esm/src/lib/event/EventManager.d.ts.map +1 -0
  128. package/dist/esm/src/lib/event/EventManager.js +45 -0
  129. package/dist/esm/src/lib/event/EventManager.js.map +1 -0
  130. package/dist/esm/src/lib/event/constants.d.ts +4 -0
  131. package/dist/esm/src/lib/event/constants.d.ts.map +1 -0
  132. package/dist/esm/src/lib/event/constants.js +4 -0
  133. package/dist/esm/src/lib/event/constants.js.map +1 -0
  134. package/dist/esm/src/lib/event/index.d.ts +1 -0
  135. package/dist/esm/src/lib/event/index.d.ts.map +1 -1
  136. package/dist/esm/src/lib/event/index.js +1 -0
  137. package/dist/esm/src/lib/event/index.js.map +1 -1
  138. package/dist/esm/src/lib/event/type.d.ts +5 -3
  139. package/dist/esm/src/lib/event/type.d.ts.map +1 -1
  140. package/dist/esm/src/lib/event/utils.d.ts +4 -0
  141. package/dist/esm/src/lib/event/utils.d.ts.map +1 -0
  142. package/dist/esm/src/lib/event/utils.js +13 -0
  143. package/dist/esm/src/lib/event/utils.js.map +1 -0
  144. package/dist/esm/src/lib/queue/EventQueue.d.ts +1 -0
  145. package/dist/esm/src/lib/queue/EventQueue.d.ts.map +1 -1
  146. package/dist/esm/src/lib/queue/EventQueue.js +20 -12
  147. package/dist/esm/src/lib/queue/EventQueue.js.map +1 -1
  148. package/dist/esm/src/lib/ramda/internal/_curry1.d.ts +10 -0
  149. package/dist/esm/src/lib/ramda/internal/_curry1.d.ts.map +1 -0
  150. package/dist/esm/src/lib/ramda/internal/_curry1.js +20 -0
  151. package/dist/esm/src/lib/ramda/internal/_curry1.js.map +1 -0
  152. package/dist/esm/src/lib/ramda/internal/_curry2.d.ts +10 -0
  153. package/dist/esm/src/lib/ramda/internal/_curry2.d.ts.map +1 -0
  154. package/dist/esm/src/lib/ramda/internal/_curry2.js +37 -0
  155. package/dist/esm/src/lib/ramda/internal/_curry2.js.map +1 -0
  156. package/dist/esm/src/lib/ramda/internal/_curry3.d.ts +10 -0
  157. package/dist/esm/src/lib/ramda/internal/_curry3.d.ts.map +1 -0
  158. package/dist/esm/src/lib/ramda/internal/_curry3.js +68 -0
  159. package/dist/esm/src/lib/ramda/internal/_curry3.js.map +1 -0
  160. package/dist/esm/src/lib/ramda/internal/_has.d.ts +2 -0
  161. package/dist/esm/src/lib/ramda/internal/_has.d.ts.map +1 -0
  162. package/dist/esm/src/lib/ramda/internal/_has.js +4 -0
  163. package/dist/esm/src/lib/ramda/internal/_has.js.map +1 -0
  164. package/dist/esm/src/lib/ramda/internal/_isObject.d.ts +2 -0
  165. package/dist/esm/src/lib/ramda/internal/_isObject.d.ts.map +1 -0
  166. package/dist/esm/src/lib/ramda/internal/_isObject.js +4 -0
  167. package/dist/esm/src/lib/ramda/internal/_isObject.js.map +1 -0
  168. package/dist/esm/src/lib/ramda/internal/_isPlaceholder.d.ts +2 -0
  169. package/dist/esm/src/lib/ramda/internal/_isPlaceholder.d.ts.map +1 -0
  170. package/dist/esm/src/lib/ramda/internal/_isPlaceholder.js +4 -0
  171. package/dist/esm/src/lib/ramda/internal/_isPlaceholder.js.map +1 -0
  172. package/dist/esm/src/lib/ramda/mergeDeepRight.d.ts +3 -0
  173. package/dist/esm/src/lib/ramda/mergeDeepRight.d.ts.map +1 -0
  174. package/dist/esm/src/lib/ramda/mergeDeepRight.js +9 -0
  175. package/dist/esm/src/lib/ramda/mergeDeepRight.js.map +1 -0
  176. package/dist/esm/src/lib/ramda/mergeDeepWithKey.d.ts +3 -0
  177. package/dist/esm/src/lib/ramda/mergeDeepWithKey.d.ts.map +1 -0
  178. package/dist/esm/src/lib/ramda/mergeDeepWithKey.js +15 -0
  179. package/dist/esm/src/lib/ramda/mergeDeepWithKey.js.map +1 -0
  180. package/dist/esm/src/lib/ramda/mergeWithKey.d.ts +3 -0
  181. package/dist/esm/src/lib/ramda/mergeWithKey.d.ts.map +1 -0
  182. package/dist/esm/src/lib/ramda/mergeWithKey.js +21 -0
  183. package/dist/esm/src/lib/ramda/mergeWithKey.js.map +1 -0
  184. package/dist/esm/src/lib/storage/native.d.ts +1 -0
  185. package/dist/esm/src/lib/storage/native.d.ts.map +1 -1
  186. package/dist/esm/src/lib/storage/native.js +3 -0
  187. package/dist/esm/src/lib/storage/native.js.map +1 -1
  188. package/dist/esm/src/lib/version.d.ts +2 -0
  189. package/dist/esm/src/lib/version.d.ts.map +1 -0
  190. package/dist/esm/src/lib/version.js +3 -0
  191. package/dist/esm/src/lib/version.js.map +1 -0
  192. package/dist/esm/src/types/base.d.ts +1 -0
  193. package/dist/esm/src/types/base.d.ts.map +1 -1
  194. package/dist/esm/src/types/events.d.ts +55 -27
  195. package/dist/esm/src/types/events.d.ts.map +1 -1
  196. package/dist/esm/src/types/events.js.map +1 -1
  197. package/dist/esm/src/utils/base.d.ts +1 -1
  198. package/dist/esm/src/utils/base.d.ts.map +1 -1
  199. package/dist/esm/src/utils/base.js +2 -2
  200. package/dist/esm/src/utils/base.js.map +1 -1
  201. package/dist/esm/src/utils/timestamp.d.ts +8 -0
  202. package/dist/esm/src/utils/timestamp.d.ts.map +1 -0
  203. package/dist/esm/src/utils/timestamp.js +8 -0
  204. package/dist/esm/src/utils/timestamp.js.map +1 -0
  205. package/dist/esm/src/validators/checks.d.ts +77 -0
  206. package/dist/esm/src/validators/checks.d.ts.map +1 -0
  207. package/dist/esm/src/validators/checks.js +119 -0
  208. package/dist/esm/src/validators/checks.js.map +1 -0
  209. package/dist/esm/src/validators/index.d.ts +1 -1
  210. package/dist/esm/src/validators/index.d.ts.map +1 -1
  211. package/dist/esm/src/validators/index.js +1 -1
  212. package/dist/esm/src/validators/index.js.map +1 -1
  213. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  214. package/dist/index.umd.min.js +1 -1
  215. package/dist/index.umd.min.js.map +1 -1
  216. package/package.json +3 -2
  217. package/src/FormoAnalytics.ts +380 -242
  218. package/src/FormoAnalyticsProvider.tsx +5 -5
  219. package/src/constants/config.ts +1 -1
  220. package/src/constants/events.ts +15 -4
  221. package/src/lib/event/EventFactory.ts +358 -163
  222. package/src/lib/event/EventManager.ts +39 -0
  223. package/src/lib/event/constants.ts +4 -0
  224. package/src/lib/event/index.ts +1 -0
  225. package/src/lib/event/type.ts +6 -8
  226. package/src/lib/event/utils.ts +15 -0
  227. package/src/lib/queue/EventQueue.ts +22 -10
  228. package/src/lib/ramda/internal/_curry1.ts +19 -0
  229. package/src/lib/ramda/internal/_curry2.ts +37 -0
  230. package/src/lib/ramda/internal/_curry3.ts +68 -0
  231. package/src/lib/ramda/internal/_has.ts +3 -0
  232. package/src/lib/ramda/internal/_isObject.ts +3 -0
  233. package/src/lib/ramda/internal/_isPlaceholder.ts +5 -0
  234. package/src/lib/ramda/mergeDeepRight.ts +13 -0
  235. package/src/lib/ramda/mergeDeepWithKey.ts +22 -0
  236. package/src/lib/ramda/mergeWithKey.ts +28 -0
  237. package/src/lib/storage/native.ts +4 -0
  238. package/src/lib/version.ts +2 -0
  239. package/src/types/base.ts +1 -0
  240. package/src/types/events.ts +93 -58
  241. package/src/utils/base.ts +2 -2
  242. package/src/utils/timestamp.ts +9 -0
  243. package/src/validators/checks.ts +160 -0
  244. package/src/validators/index.ts +1 -1
  245. package/tsconfig.json +1 -1
  246. package/dist/cjs/src/validators/type-check.d.ts +0 -14
  247. package/dist/cjs/src/validators/type-check.d.ts.map +0 -1
  248. package/dist/cjs/src/validators/type-check.js +0 -61
  249. package/dist/cjs/src/validators/type-check.js.map +0 -1
  250. package/dist/esm/src/validators/type-check.d.ts +0 -14
  251. package/dist/esm/src/validators/type-check.d.ts.map +0 -1
  252. package/dist/esm/src/validators/type-check.js +0 -46
  253. package/dist/esm/src/validators/type-check.js.map +0 -1
  254. 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,235 @@ 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,
68
- href: url.href,
94
+ // contextual properties
95
+ const defaultContext = {
96
+ user_agent: globalThis.navigator.userAgent,
69
97
  locale: language,
98
+ timezone,
70
99
  location,
100
+ referrer: document.referrer,
101
+ ...this.extractUTMParameters(globalThis.location.href),
102
+ ref: params.get("ref")?.trim() || "",
103
+ page_path: path,
104
+ page_title: document.title,
105
+ page_url: url.href,
106
+ library_name: "Formo Web SDK",
107
+ library_version,
71
108
  };
109
+
110
+ const mergedContext = mergeDeepRight(
111
+ defaultContext,
112
+ context || {}
113
+ ) as IFormoEventContext;
114
+
115
+ return mergedContext;
72
116
  }
73
117
 
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;
118
+ /**
119
+ * Add any missing default page properties using values from options and defaults
120
+ * @param properties Input page properties
121
+ * @param options API options
122
+ */
123
+ private getPageProperties = (
124
+ properties: IFormoEventProperties
125
+ ): IFormoEventProperties => {
126
+ const pageProps = properties;
79
127
 
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() || "",
128
+ if (isUndefined(pageProps.url)) {
129
+ pageProps.url = new URL(globalThis.location.href).href;
130
+ }
131
+
132
+ if (isUndefined(pageProps.path)) {
133
+ pageProps.path = globalThis.location.pathname;
134
+ }
135
+
136
+ if (isUndefined(pageProps.hash)) {
137
+ pageProps.hash = globalThis.location.hash;
138
+ }
139
+
140
+ return pageProps;
141
+ };
142
+
143
+ private getEnrichedEvent = (
144
+ formoEvent: Partial<IFormoEvent>,
145
+ context?: IFormoEventContext
146
+ ): IFormoEvent => {
147
+ const commonEventData = {
148
+ context: this.generateContext(context),
149
+ original_timestamp: getCurrentTimeFormatted(),
150
+ user_id: formoEvent.user_id,
151
+ type: formoEvent.type,
152
+ channel: CHANNEL,
153
+ version: VERSION,
154
+ } as Partial<IFormoEvent>;
155
+
156
+ if (!local.isAvailable()) {
157
+ commonEventData.anonymous_id = generateNativeUUID();
158
+ } else {
159
+ commonEventData.anonymous_id = generateAnonymousId();
160
+ }
161
+
162
+ if (formoEvent.address) {
163
+ commonEventData.address = toChecksumAddress(formoEvent.address);
164
+ } else {
165
+ commonEventData.address = formoEvent.address;
166
+ }
167
+
168
+ const processedEvent = mergeDeepRight(
169
+ formoEvent,
170
+ commonEventData
171
+ ) as IFormoEvent;
172
+
173
+ if (processedEvent.event === undefined) {
174
+ processedEvent.event = null;
175
+ }
176
+
177
+ if (processedEvent.properties === undefined) {
178
+ processedEvent.properties = null;
179
+ }
180
+
181
+ return toSnakeCase(processedEvent);
182
+ };
183
+
184
+ generatePageEvent(
185
+ category?: string,
186
+ name?: string,
187
+ properties?: IFormoEventProperties,
188
+ context?: IFormoEventContext
189
+ ): IFormoEvent {
190
+ let props = properties ?? {};
191
+ props.category = category;
192
+ props.name = name;
193
+ props = this.getPageProperties(props);
194
+
195
+ const pageEvent: Partial<IFormoEvent> = {
196
+ properties: props,
197
+ type: "page",
90
198
  };
199
+
200
+ return this.getEnrichedEvent(pageEvent, context);
91
201
  }
92
202
 
93
- generateConnectEvent(chainId: ChainID, address: Address) {
94
- return {
95
- chainId,
96
- address,
203
+ generateDetectWalletEvent(
204
+ providerName: string,
205
+ rdns: string,
206
+ properties?: IFormoEventProperties,
207
+ context?: IFormoEventContext
208
+ ) {
209
+ const detectEvent: Partial<IFormoEvent> = {
210
+ properties: {
211
+ providerName,
212
+ rdns,
213
+ ...properties,
214
+ },
215
+ type: "detect",
97
216
  };
217
+
218
+ return this.getEnrichedEvent(detectEvent, context);
98
219
  }
99
220
 
100
- generateDisconnectEvent(chainId: ChainID, address: Address) {
101
- return {
102
- chainId,
221
+ generateIdentifyEvent(
222
+ providerName: string,
223
+ rdns: string,
224
+ address: Nullable<Address>,
225
+ userId?: Nullable<string>,
226
+ properties?: IFormoEventProperties,
227
+ context?: IFormoEventContext
228
+ ) {
229
+ const identifyEvent: Partial<IFormoEvent> = {
230
+ properties: {
231
+ providerName,
232
+ rdns,
233
+ ...properties,
234
+ },
235
+ user_id: userId,
103
236
  address,
237
+ type: "identify",
104
238
  };
239
+
240
+ return this.getEnrichedEvent(identifyEvent, context);
105
241
  }
106
242
 
107
- generateDetectWalletEvent(providerName: string, rdns: string) {
108
- return {
109
- providerName,
110
- rdns,
243
+ generateConnectEvent(
244
+ chainId: ChainID,
245
+ address: Address,
246
+ properties?: IFormoEventProperties,
247
+ context?: IFormoEventContext
248
+ ) {
249
+ const connectEvent: Partial<IFormoEvent> = {
250
+ properties: {
251
+ chainId,
252
+ ...properties,
253
+ },
254
+ address,
255
+ type: "connect",
111
256
  };
257
+
258
+ return this.getEnrichedEvent(connectEvent, context);
112
259
  }
113
260
 
114
- generateIdentifyEvent(
115
- address: Address | null,
116
- providerName: string,
117
- rdns: string
261
+ generateDisconnectEvent(
262
+ chainId: ChainID,
263
+ address: Address,
264
+ properties?: IFormoEventProperties,
265
+ context?: IFormoEventContext
118
266
  ) {
119
- return {
267
+ const disconnectEvent: Partial<IFormoEvent> = {
268
+ properties: {
269
+ chainId,
270
+ ...properties,
271
+ },
120
272
  address,
121
- providerName,
122
- rdns,
273
+ type: "disconnect",
123
274
  };
275
+
276
+ return this.getEnrichedEvent(disconnectEvent, context);
124
277
  }
125
278
 
126
- generateChainChangedEvent(chainId: ChainID, address: Address) {
127
- return {
128
- chainId,
279
+ generateChainChangedEvent(
280
+ chainId: ChainID,
281
+ address: Address,
282
+ properties?: IFormoEventProperties,
283
+ context?: IFormoEventContext
284
+ ) {
285
+ const chainEvent: Partial<IFormoEvent> = {
286
+ properties: {
287
+ chainId,
288
+ ...properties,
289
+ },
129
290
  address,
291
+ type: "chain",
130
292
  };
293
+
294
+ return this.getEnrichedEvent(chainEvent, context);
131
295
  }
132
296
 
133
297
  generateSignatureEvent(
@@ -135,15 +299,23 @@ class EventFactory implements IEventFactory {
135
299
  chainId: ChainID,
136
300
  address: Address,
137
301
  message: string,
138
- signatureHash: string
302
+ signatureHash: string,
303
+ properties?: IFormoEventProperties,
304
+ context?: IFormoEventContext
139
305
  ) {
140
- return {
141
- status,
142
- chainId,
306
+ const signatureEvent: Partial<IFormoEvent> = {
307
+ properties: {
308
+ status,
309
+ chainId,
310
+ message,
311
+ signatureHash,
312
+ ...properties,
313
+ },
143
314
  address,
144
- message,
145
- signatureHash,
315
+ type: "signature",
146
316
  };
317
+
318
+ return this.getEnrichedEvent(signatureEvent, context);
147
319
  }
148
320
 
149
321
  generateTransactionEvent(
@@ -153,110 +325,133 @@ class EventFactory implements IEventFactory {
153
325
  data: string,
154
326
  to: string,
155
327
  value: string,
156
- transactionHash: string
328
+ transactionHash: string,
329
+ properties?: IFormoEventProperties,
330
+ context?: IFormoEventContext
157
331
  ) {
158
- return {
159
- status,
160
- chainId,
332
+ const transactionEvent: Partial<IFormoEvent> = {
333
+ properties: {
334
+ status,
335
+ chainId,
336
+ data,
337
+ to,
338
+ value,
339
+ transactionHash,
340
+ ...properties,
341
+ },
161
342
  address,
162
- data,
163
- to,
164
- value,
165
- transactionHash,
343
+ type: "transaction",
166
344
  };
167
- }
168
345
 
169
- generateCustomEvent(args: any) {
170
- if (typeof args !== "object") {
171
- logger.warn("Invalid event data");
172
- return {};
173
- }
174
- const { action, ...rest } = args;
346
+ return this.getEnrichedEvent(transactionEvent, context);
347
+ }
175
348
 
176
- return {
177
- ...rest,
349
+ generateTrackEvent(
350
+ event: string,
351
+ properties?: IFormoEventProperties,
352
+ context?: IFormoEventContext
353
+ ) {
354
+ const transactionEvent: Partial<IFormoEvent> = {
355
+ properties,
356
+ event,
357
+ type: "track",
178
358
  };
359
+
360
+ return this.getEnrichedEvent(transactionEvent, context);
179
361
  }
180
362
 
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
- }
363
+ // Returns an event with type, context, properties, and common properties
364
+ create(event: APIEvent, address?: Address, userId?: string): IFormoEvent {
365
+ let formoEvent: Partial<IFormoEvent> = {};
249
366
 
250
- return toSnakeCase(
251
- {
252
- ...commonProperties,
253
- payload: {
254
- ...payload,
255
- ...eventSpecificPayload,
256
- },
257
- },
258
- ["user-agent"]
259
- );
367
+ formoEvent.address = address || null;
368
+ formoEvent.user_id = userId || null;
369
+
370
+ switch (event.type) {
371
+ case "page":
372
+ formoEvent = this.generatePageEvent(
373
+ event.category,
374
+ event.name,
375
+ event.properties,
376
+ event.context
377
+ );
378
+ break;
379
+ case "detect":
380
+ formoEvent = this.generateDetectWalletEvent(
381
+ event.providerName,
382
+ event.rdns,
383
+ event.properties,
384
+ event.context
385
+ );
386
+ break;
387
+ case "identify":
388
+ formoEvent = this.generateIdentifyEvent(
389
+ event.providerName,
390
+ event.rdns,
391
+ event.address,
392
+ event.userId,
393
+ event.properties,
394
+ event.context
395
+ );
396
+ break;
397
+ case "chain":
398
+ formoEvent = this.generateChainChangedEvent(
399
+ event.chainId,
400
+ event.address,
401
+ event.properties,
402
+ event.context
403
+ );
404
+ break;
405
+ case "connect":
406
+ formoEvent = this.generateConnectEvent(
407
+ event.chainId,
408
+ event.address,
409
+ event.properties,
410
+ event.context
411
+ );
412
+ break;
413
+ case "disconnect":
414
+ formoEvent = this.generateDisconnectEvent(
415
+ event.chainId,
416
+ event.address,
417
+ event.properties,
418
+ event.context
419
+ );
420
+ break;
421
+ case "signature":
422
+ formoEvent = this.generateSignatureEvent(
423
+ event.status,
424
+ event.chainId,
425
+ event.address,
426
+ event.message,
427
+ event.signatureHash,
428
+ event.properties,
429
+ event.context
430
+ );
431
+ break;
432
+ case "transaction":
433
+ formoEvent = this.generateTransactionEvent(
434
+ event.status,
435
+ event.chainId,
436
+ event.address,
437
+ event.data,
438
+ event.to,
439
+ event.value,
440
+ event.transactionHash,
441
+ event.properties,
442
+ event.context
443
+ );
444
+ break;
445
+ case "track":
446
+ default:
447
+ formoEvent = this.generateTrackEvent(
448
+ event.event,
449
+ event.properties,
450
+ event.context
451
+ );
452
+ break;
453
+ }
454
+ return formoEvent as IFormoEvent;
260
455
  }
261
456
  }
262
457