@formo/analytics 1.19.10 → 1.21.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 (55) hide show
  1. package/README.md +3 -1
  2. package/dist/cjs/src/FormoAnalytics.d.ts +17 -1
  3. package/dist/cjs/src/FormoAnalytics.js +150 -82
  4. package/dist/cjs/src/FormoAnalyticsProvider.js +5 -1
  5. package/dist/cjs/src/constants/base.d.ts +4 -0
  6. package/dist/cjs/src/constants/base.js +8 -1
  7. package/dist/cjs/src/lib/browser/browsers.d.ts +3 -0
  8. package/dist/cjs/src/lib/browser/browsers.js +132 -0
  9. package/dist/cjs/src/lib/consent.d.ts +35 -0
  10. package/dist/cjs/src/lib/consent.js +102 -0
  11. package/dist/cjs/src/lib/event/EventFactory.d.ts +10 -10
  12. package/dist/cjs/src/lib/event/EventFactory.js +272 -140
  13. package/dist/cjs/src/lib/event/EventManager.d.ts +1 -1
  14. package/dist/cjs/src/lib/event/EventManager.js +62 -9
  15. package/dist/cjs/src/lib/event/type.d.ts +2 -2
  16. package/dist/cjs/src/lib/index.d.ts +1 -0
  17. package/dist/cjs/src/lib/index.js +1 -0
  18. package/dist/cjs/src/lib/storage/built-in/blueprint.js +2 -1
  19. package/dist/cjs/src/lib/version.d.ts +1 -1
  20. package/dist/cjs/src/lib/version.js +1 -1
  21. package/dist/cjs/src/types/base.d.ts +3 -0
  22. package/dist/cjs/src/utils/address.d.ts +7 -0
  23. package/dist/cjs/src/utils/address.js +21 -1
  24. package/dist/cjs/src/utils/hash.d.ts +10 -0
  25. package/dist/cjs/src/utils/hash.js +21 -0
  26. package/dist/cjs/src/utils/index.d.ts +1 -0
  27. package/dist/cjs/src/utils/index.js +1 -0
  28. package/dist/esm/src/FormoAnalytics.d.ts +17 -1
  29. package/dist/esm/src/FormoAnalytics.js +152 -84
  30. package/dist/esm/src/FormoAnalyticsProvider.js +5 -1
  31. package/dist/esm/src/constants/base.d.ts +4 -0
  32. package/dist/esm/src/constants/base.js +7 -0
  33. package/dist/esm/src/lib/browser/browsers.d.ts +3 -0
  34. package/dist/esm/src/lib/browser/browsers.js +129 -0
  35. package/dist/esm/src/lib/consent.d.ts +35 -0
  36. package/dist/esm/src/lib/consent.js +97 -0
  37. package/dist/esm/src/lib/event/EventFactory.d.ts +10 -10
  38. package/dist/esm/src/lib/event/EventFactory.js +272 -140
  39. package/dist/esm/src/lib/event/EventManager.d.ts +1 -1
  40. package/dist/esm/src/lib/event/EventManager.js +62 -9
  41. package/dist/esm/src/lib/event/type.d.ts +2 -2
  42. package/dist/esm/src/lib/index.d.ts +1 -0
  43. package/dist/esm/src/lib/index.js +1 -0
  44. package/dist/esm/src/lib/storage/built-in/blueprint.js +2 -1
  45. package/dist/esm/src/lib/version.d.ts +1 -1
  46. package/dist/esm/src/lib/version.js +1 -1
  47. package/dist/esm/src/types/base.d.ts +3 -0
  48. package/dist/esm/src/utils/address.d.ts +7 -0
  49. package/dist/esm/src/utils/address.js +19 -0
  50. package/dist/esm/src/utils/hash.d.ts +10 -0
  51. package/dist/esm/src/utils/hash.js +18 -0
  52. package/dist/esm/src/utils/index.d.ts +1 -0
  53. package/dist/esm/src/utils/index.js +1 -0
  54. package/dist/index.umd.min.js +1 -1
  55. package/package.json +2 -2
@@ -0,0 +1,129 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
12
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ var inFlight = null;
38
+ var cached = null;
39
+ function getUA() {
40
+ try {
41
+ return typeof globalThis.navigator !== "undefined"
42
+ ? globalThis.navigator.userAgent
43
+ : "";
44
+ }
45
+ catch (_a) {
46
+ return "";
47
+ }
48
+ }
49
+ function isBraveHeuristic() {
50
+ return __awaiter(this, void 0, void 0, function () {
51
+ var nav, ok, _a, brands;
52
+ var _b, _c;
53
+ return __generator(this, function (_d) {
54
+ switch (_d.label) {
55
+ case 0:
56
+ nav = typeof globalThis.navigator !== "undefined"
57
+ ? globalThis.navigator
58
+ : undefined;
59
+ if (!nav)
60
+ return [2 /*return*/, false];
61
+ _d.label = 1;
62
+ case 1:
63
+ _d.trys.push([1, 4, , 5]);
64
+ if (!((_b = nav.brave) === null || _b === void 0 ? void 0 : _b.isBrave)) return [3 /*break*/, 3];
65
+ return [4 /*yield*/, nav.brave.isBrave().catch(function () { return false; })];
66
+ case 2:
67
+ ok = _d.sent();
68
+ if (ok)
69
+ return [2 /*return*/, true];
70
+ _d.label = 3;
71
+ case 3: return [3 /*break*/, 5];
72
+ case 4:
73
+ _a = _d.sent();
74
+ return [3 /*break*/, 5];
75
+ case 5:
76
+ try {
77
+ brands = (_c = nav.userAgentData) === null || _c === void 0 ? void 0 : _c.brands;
78
+ if (brands === null || brands === void 0 ? void 0 : brands.some(function (b) { return /Brave/i.test(b.brand); }))
79
+ return [2 /*return*/, true];
80
+ }
81
+ catch (_e) { }
82
+ try {
83
+ if (/Brave/i.test(nav.userAgent))
84
+ return [2 /*return*/, true];
85
+ }
86
+ catch (_f) { }
87
+ return [2 /*return*/, false];
88
+ }
89
+ });
90
+ });
91
+ }
92
+ function classifyNonBrave(ua) {
93
+ if (/Firefox\/\d+/i.test(ua))
94
+ return "firefox";
95
+ if (/Edg\/\d+/i.test(ua))
96
+ return "edge";
97
+ if (/OPR\/\d+/i.test(ua))
98
+ return "opera";
99
+ if (/Safari\/\d+/i.test(ua) && !/Chrome\/\d+/i.test(ua))
100
+ return "safari";
101
+ if (/Chrome\/\d+/i.test(ua))
102
+ return "chrome";
103
+ return "unknown";
104
+ }
105
+ export function detectBrowser() {
106
+ var _this = this;
107
+ if (cached)
108
+ return Promise.resolve(cached);
109
+ if (inFlight)
110
+ return inFlight;
111
+ inFlight = (function () { return __awaiter(_this, void 0, void 0, function () {
112
+ var ua, brave;
113
+ return __generator(this, function (_a) {
114
+ switch (_a.label) {
115
+ case 0:
116
+ ua = getUA();
117
+ return [4 /*yield*/, isBraveHeuristic().catch(function () { return false; })];
118
+ case 1:
119
+ brave = _a.sent();
120
+ cached = brave ? "brave" : classifyNonBrave(ua);
121
+ return [2 /*return*/, cached];
122
+ }
123
+ });
124
+ }); })().finally(function () {
125
+ inFlight = null; // subsequent calls hit cache
126
+ });
127
+ return inFlight;
128
+ }
129
+ //# sourceMappingURL=browsers.js.map
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Consent management utilities for handling tracking consent flags in cookies.
3
+ * These functions bypass the consent-aware storage system to ensure consent
4
+ * preferences are always stored persistently for compliance purposes.
5
+ *
6
+ * All consent cookies are project-specific to avoid conflicts between different
7
+ * Formo projects on the same domain.
8
+ */
9
+ /**
10
+ * Set a consent flag directly in cookies, bypassing the consent-aware storage system.
11
+ * Uses cookies for consent storage to ensure:
12
+ * - Cross-domain/subdomain compatibility
13
+ * - Server-side accessibility for compliance auditing
14
+ * - Regulatory compliance (GDPR/CCPA requirements)
15
+ * - Explicit expiration handling
16
+ * - Project isolation (no conflicts between different Formo projects)
17
+ * @param projectId - The project identifier (writeKey)
18
+ * @param key - The cookie key
19
+ * @param value - The cookie value
20
+ */
21
+ export declare function setConsentFlag(projectId: string, key: string, value: string): void;
22
+ /**
23
+ * Get a consent flag directly from cookies, bypassing the consent-aware storage system
24
+ * @param projectId - The project identifier (writeKey)
25
+ * @param key - The cookie key
26
+ * @returns The cookie value or null if not found
27
+ */
28
+ export declare function getConsentFlag(projectId: string, key: string): string | null;
29
+ /**
30
+ * Remove a consent flag directly from cookies, bypassing the consent-aware storage system
31
+ * @param projectId - The project identifier (writeKey)
32
+ * @param key - The cookie key
33
+ */
34
+ export declare function removeConsentFlag(projectId: string, key: string): void;
35
+ //# sourceMappingURL=consent.d.ts.map
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Consent management utilities for handling tracking consent flags in cookies.
3
+ * These functions bypass the consent-aware storage system to ensure consent
4
+ * preferences are always stored persistently for compliance purposes.
5
+ *
6
+ * All consent cookies are project-specific to avoid conflicts between different
7
+ * Formo projects on the same domain.
8
+ */
9
+ import { secureHash } from '../utils/hash';
10
+ /**
11
+ * Generate a project-specific cookie key to avoid conflicts between different Formo projects
12
+ * Uses hashed writeKey for privacy and security
13
+ * @param projectId - The project identifier (writeKey)
14
+ * @param key - The base cookie key
15
+ * @returns Project-specific cookie key
16
+ */
17
+ function getProjectSpecificKey(projectId, key) {
18
+ return "formo_".concat(secureHash(projectId), "_").concat(key);
19
+ }
20
+ /**
21
+ * Set a consent flag directly in cookies, bypassing the consent-aware storage system.
22
+ * Uses cookies for consent storage to ensure:
23
+ * - Cross-domain/subdomain compatibility
24
+ * - Server-side accessibility for compliance auditing
25
+ * - Regulatory compliance (GDPR/CCPA requirements)
26
+ * - Explicit expiration handling
27
+ * - Project isolation (no conflicts between different Formo projects)
28
+ * @param projectId - The project identifier (writeKey)
29
+ * @param key - The cookie key
30
+ * @param value - The cookie value
31
+ */
32
+ export function setConsentFlag(projectId, key, value) {
33
+ var _a;
34
+ if (typeof document !== 'undefined') {
35
+ var projectSpecificKey = getProjectSpecificKey(projectId, key);
36
+ var expires = new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toUTCString(); // 1 year (GDPR compliant)
37
+ var isSecure = ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.protocol) === 'https:';
38
+ // Enhanced privacy settings: Secure (HTTPS), SameSite=Strict for consent cookies
39
+ document.cookie = "".concat(projectSpecificKey, "=").concat(encodeURIComponent(value), "; expires=").concat(expires, "; path=/; SameSite=Strict").concat(isSecure ? '; Secure' : '');
40
+ }
41
+ }
42
+ /**
43
+ * Get a consent flag directly from cookies, bypassing the consent-aware storage system
44
+ * @param projectId - The project identifier (writeKey)
45
+ * @param key - The cookie key
46
+ * @returns The cookie value or null if not found
47
+ */
48
+ export function getConsentFlag(projectId, key) {
49
+ if (typeof document === 'undefined')
50
+ return null;
51
+ var projectSpecificKey = getProjectSpecificKey(projectId, key);
52
+ var cookies = document.cookie.split(';');
53
+ for (var _i = 0, cookies_1 = cookies; _i < cookies_1.length; _i++) {
54
+ var cookie = cookies_1[_i];
55
+ var trimmed = cookie.trim();
56
+ var eqIdx = trimmed.indexOf('=');
57
+ if (eqIdx === -1)
58
+ continue;
59
+ var cookieKey = trimmed.substring(0, eqIdx);
60
+ var cookieValue = trimmed.substring(eqIdx + 1);
61
+ if (cookieKey === projectSpecificKey) {
62
+ return decodeURIComponent(cookieValue || '');
63
+ }
64
+ }
65
+ return null;
66
+ }
67
+ /**
68
+ * Remove a consent flag directly from cookies, bypassing the consent-aware storage system
69
+ * @param projectId - The project identifier (writeKey)
70
+ * @param key - The cookie key
71
+ */
72
+ export function removeConsentFlag(projectId, key) {
73
+ var projectSpecificKey = getProjectSpecificKey(projectId, key);
74
+ deleteCookieDirectly(projectSpecificKey);
75
+ }
76
+ /**
77
+ * Delete a cookie directly, handling various domain scenarios
78
+ * @param cookieName - The name of the cookie to delete
79
+ */
80
+ function deleteCookieDirectly(cookieName) {
81
+ if (typeof document === 'undefined')
82
+ return;
83
+ // Clear from current domain/path
84
+ document.cookie = "".concat(cookieName, "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;");
85
+ // Try to clear from parent domain if it's a proper multi-level domain
86
+ if (typeof window !== 'undefined') {
87
+ var hostname = window.location.hostname;
88
+ var parts = hostname.split('.');
89
+ // Only try parent domain deletion for proper domains with multiple parts
90
+ // Skip localhost and single-level domains
91
+ if (parts.length >= 2 && hostname !== 'localhost') {
92
+ var domain = parts.slice(-2).join('.');
93
+ document.cookie = "".concat(cookieName, "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.").concat(domain, ";");
94
+ }
95
+ }
96
+ }
97
+ //# sourceMappingURL=consent.js.map
@@ -16,16 +16,16 @@ declare class EventFactory implements IEventFactory {
16
16
  */
17
17
  private getPageProperties;
18
18
  private getEnrichedEvent;
19
- generatePageEvent(category?: string, name?: string, properties?: IFormoEventProperties, context?: IFormoEventContext): IFormoEvent;
20
- generateDetectWalletEvent(providerName: string, rdns: string, properties?: IFormoEventProperties, context?: IFormoEventContext): IFormoEvent;
21
- generateIdentifyEvent(providerName: string, rdns: string, address: Nullable<Address>, userId?: Nullable<string>, properties?: IFormoEventProperties, context?: IFormoEventContext): IFormoEvent;
22
- generateConnectEvent(chainId: ChainID, address: Address, properties?: IFormoEventProperties, context?: IFormoEventContext): IFormoEvent;
23
- generateDisconnectEvent(chainId?: ChainID, address?: Address, properties?: IFormoEventProperties, context?: IFormoEventContext): IFormoEvent;
24
- generateChainChangedEvent(chainId: ChainID, address: Address, properties?: IFormoEventProperties, context?: IFormoEventContext): IFormoEvent;
25
- generateSignatureEvent(status: SignatureStatus, chainId: ChainID, address: Address, message: string, signatureHash?: string, properties?: IFormoEventProperties, context?: IFormoEventContext): IFormoEvent;
26
- generateTransactionEvent(status: TransactionStatus, chainId: ChainID, address: Address, data: string, to: string, value: string, transactionHash?: string, properties?: IFormoEventProperties, context?: IFormoEventContext): IFormoEvent;
27
- generateTrackEvent(event: string, properties?: IFormoEventProperties, context?: IFormoEventContext): IFormoEvent;
28
- create(event: APIEvent, address?: Address, userId?: string): IFormoEvent;
19
+ generatePageEvent(category?: string, name?: string, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
20
+ generateDetectWalletEvent(providerName: string, rdns: string, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
21
+ generateIdentifyEvent(providerName: string, rdns: string, address: Nullable<Address>, userId?: Nullable<string>, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
22
+ generateConnectEvent(chainId: ChainID, address: Address, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
23
+ generateDisconnectEvent(chainId?: ChainID, address?: Address, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
24
+ generateChainChangedEvent(chainId: ChainID, address: Address, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
25
+ generateSignatureEvent(status: SignatureStatus, chainId: ChainID, address: Address, message: string, signatureHash?: string, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
26
+ generateTransactionEvent(status: TransactionStatus, chainId: ChainID, address: Address, data: string, to: string, value: string, transactionHash?: string, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
27
+ generateTrackEvent(event: string, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
28
+ create(event: APIEvent, address?: Address, userId?: string): Promise<IFormoEvent>;
29
29
  }
30
30
  export { EventFactory };
31
31
  //# sourceMappingURL=EventFactory.d.ts.map