@shware/analytics 8.15.1 → 8.16.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 (47) hide show
  1. package/dist/attribution/classify.cjs +15 -3
  2. package/dist/attribution/classify.cjs.map +1 -1
  3. package/dist/attribution/classify.d.cts +2 -1
  4. package/dist/attribution/classify.d.cts.map +1 -1
  5. package/dist/attribution/classify.d.mts +2 -1
  6. package/dist/attribution/classify.d.mts.map +1 -1
  7. package/dist/attribution/classify.mjs +15 -3
  8. package/dist/attribution/classify.mjs.map +1 -1
  9. package/dist/attribution/vocabulary.cjs +100 -19
  10. package/dist/attribution/vocabulary.cjs.map +1 -1
  11. package/dist/attribution/vocabulary.d.cts +16 -4
  12. package/dist/attribution/vocabulary.d.cts.map +1 -1
  13. package/dist/attribution/vocabulary.d.mts +16 -4
  14. package/dist/attribution/vocabulary.d.mts.map +1 -1
  15. package/dist/attribution/vocabulary.mjs +100 -19
  16. package/dist/attribution/vocabulary.mjs.map +1 -1
  17. package/dist/schema/index.cjs +3 -1
  18. package/dist/schema/index.cjs.map +1 -1
  19. package/dist/schema/index.d.cts +18 -6
  20. package/dist/schema/index.d.cts.map +1 -1
  21. package/dist/schema/index.d.mts +18 -6
  22. package/dist/schema/index.d.mts.map +1 -1
  23. package/dist/schema/index.mjs +3 -1
  24. package/dist/schema/index.mjs.map +1 -1
  25. package/dist/server/openai-conversions-api.cjs +1 -0
  26. package/dist/server/openai-conversions-api.cjs.map +1 -1
  27. package/dist/server/openai-conversions-api.d.cts.map +1 -1
  28. package/dist/server/openai-conversions-api.d.mts.map +1 -1
  29. package/dist/server/openai-conversions-api.mjs +1 -0
  30. package/dist/server/openai-conversions-api.mjs.map +1 -1
  31. package/dist/track/types.d.cts +3 -1
  32. package/dist/track/types.d.cts.map +1 -1
  33. package/dist/track/types.d.mts +3 -1
  34. package/dist/track/types.d.mts.map +1 -1
  35. package/dist/web/index.cjs +3 -1
  36. package/dist/web/index.cjs.map +1 -1
  37. package/dist/web/index.d.cts.map +1 -1
  38. package/dist/web/index.d.mts.map +1 -1
  39. package/dist/web/index.mjs +3 -1
  40. package/dist/web/index.mjs.map +1 -1
  41. package/dist/web/page-key.cjs +4 -2
  42. package/dist/web/page-key.cjs.map +1 -1
  43. package/dist/web/page-key.d.cts.map +1 -1
  44. package/dist/web/page-key.d.mts.map +1 -1
  45. package/dist/web/page-key.mjs +4 -2
  46. package/dist/web/page-key.mjs.map +1 -1
  47. package/package.json +1 -1
@@ -69,6 +69,7 @@ const SOURCE_ALIASES = {
69
69
  ig: "meta",
70
70
  an: "meta",
71
71
  msg: "meta",
72
+ th: "meta",
72
73
  facebook: "meta",
73
74
  instagram: "meta",
74
75
  bing: "microsoft",
@@ -87,27 +88,107 @@ const SOURCE_ALIASES = {
87
88
  "kimi.com": "kimi"
88
89
  };
89
90
  /**
90
- * Which click id belongs to which channel, in priority order. Every key is a field this SDK
91
- * collects (`AdvertisingInfo`); `fbp` and `rdt_uuid` are deliberately absent — they are pixel
92
- * browser ids, present with or without a click.
91
+ * Which click id belongs to which channel, in priority order, and whether the platform puts it on
92
+ * its ad clicks only (`'ads'`) or on other links as well (`'any'`). Every key is a field this SDK
93
+ * collects (`AdvertisingInfo`).
94
+ *
95
+ * The third column decides whether the id can say a click was paid when a `utm_source` names the
96
+ * channel but no `utm_medium` says how (a Reddit ad tagged `utm_source=reddit` and nothing more).
97
+ * `fbclid` is `'any'`: Meta decorates every outbound link with it, organic posts, profile links
98
+ * and shares included. `twclid` and `ko_click_id` are `'any'` until it is clear they never
99
+ * decorate an organic link.
100
+ *
101
+ * Deliberately absent: `fbp` and `rdt_uuid`, pixel browser ids present with or without a click;
102
+ * and `fbc`, which the SDK only ever reads from the `_fbc` cookie. That cookie lives 90 days after
103
+ * a Meta click, so counting it named every later visit — typed in, from search, from an email — a
104
+ * new Meta click. `fbclid` is read from the landing URL only, so it is this visit's click.
93
105
  */
94
106
  const CLICK_ID_CHANNELS = [
95
- ["fbclid", "meta"],
96
- ["fbc", "meta"],
97
- ["gclid", "google"],
98
- ["gbraid", "google"],
99
- ["wbraid", "google"],
100
- ["gad_source", "google"],
101
- ["gad_campaignid", "google"],
102
- ["dclid", "dv360"],
103
- ["msclkid", "microsoft"],
104
- ["ttclid", "tiktok"],
105
- ["rdt_cid", "reddit"],
106
- ["li_fat_id", "linkedin"],
107
- ["sccid", "snapchat"],
108
- ["twclid", "x"],
109
- ["ko_click_id", "kakao"],
110
- ["yclid", "yandex"]
107
+ [
108
+ "fbclid",
109
+ "meta",
110
+ "any"
111
+ ],
112
+ [
113
+ "gclid",
114
+ "google",
115
+ "ads"
116
+ ],
117
+ [
118
+ "gbraid",
119
+ "google",
120
+ "ads"
121
+ ],
122
+ [
123
+ "wbraid",
124
+ "google",
125
+ "ads"
126
+ ],
127
+ [
128
+ "gad_source",
129
+ "google",
130
+ "ads"
131
+ ],
132
+ [
133
+ "gad_campaignid",
134
+ "google",
135
+ "ads"
136
+ ],
137
+ [
138
+ "dclid",
139
+ "dv360",
140
+ "ads"
141
+ ],
142
+ [
143
+ "msclkid",
144
+ "microsoft",
145
+ "ads"
146
+ ],
147
+ [
148
+ "ttclid",
149
+ "tiktok",
150
+ "ads"
151
+ ],
152
+ [
153
+ "rdt_cid",
154
+ "reddit",
155
+ "ads"
156
+ ],
157
+ [
158
+ "li_fat_id",
159
+ "linkedin",
160
+ "ads"
161
+ ],
162
+ [
163
+ "ScCid",
164
+ "snapchat",
165
+ "ads"
166
+ ],
167
+ [
168
+ "twclid",
169
+ "x",
170
+ "any"
171
+ ],
172
+ [
173
+ "ko_click_id",
174
+ "kakao",
175
+ "any"
176
+ ],
177
+ [
178
+ "yclid",
179
+ "yandex",
180
+ "ads"
181
+ ],
182
+ [
183
+ "oppref",
184
+ "chatgpt",
185
+ "ads"
186
+ ],
187
+ [
188
+ "epik",
189
+ "pinterest",
190
+ "ads"
191
+ ]
111
192
  ];
112
193
  /**
113
194
  * A landing page reserved for one channel's ads, for ads that lost their parameters:
@@ -1 +1 @@
1
- {"version":3,"file":"vocabulary.mjs","names":[],"sources":["../../src/attribution/vocabulary.ts"],"sourcesContent":["import type { AdvertisingInfo } from '../track/types';\n\n/**\n * The vocabulary attribution is built from, shared by every product's `session` table and by the\n * dashboards that read it. Data for `classifyTouch` (./classify), which turns it into a channel;\n * a product's dashboards read the same names back. What stays with the product is its own hostnames\n * (referrer exclusions) and its landing-page conventions.\n */\n\n/** A session that arrived through nothing we can name. GA's spelling, so dashboards read as GA. */\nexport const DIRECT_CHANNEL = '(direct)';\n/** The medium of a direct session. */\nexport const NO_MEDIUM = '(none)';\n/** The medium of a tagged link that named a source but no medium. */\nexport const MEDIUM_NOT_SET = '(not set)';\n\n/** The channels the rules below can name. A `utm_source` outside this list is its own channel. */\nexport const CHANNELS = [\n 'meta',\n 'google',\n 'dv360',\n 'microsoft',\n 'tiktok',\n 'reddit',\n 'linkedin',\n 'snapchat',\n 'x',\n 'kakao',\n 'yandex',\n 'yahoo',\n 'duckduckgo',\n 'baidu',\n 'ecosia',\n 'naver',\n 'brave',\n 'pinterest',\n 'youtube',\n /** AI assistants that send people to sites: ChatGPT tags its links `utm_source=chatgpt.com`, the\n * others show as a referrer. Their own channel group, `organic_ai`, since GA4's default groups\n * would file them under Referral / Unassigned and the question \"how much does AI bring\" comes up. */\n 'chatgpt',\n 'perplexity',\n 'gemini',\n 'claude',\n 'copilot',\n 'grok',\n /** and the Chinese ones — DeepSeek, 豆包, Kimi, 通义, 腾讯元宝, 文心一言, 智谱清言 */\n 'deepseek',\n 'doubao',\n 'kimi',\n 'qwen',\n 'yuanbao',\n 'ernie',\n 'zhipu',\n /** the product's own referral programme: the session came through a member's link or code.\n * How a product recognises one (a `/refer/<code>` path, a code at sign-up) is its own rule. Not\n * `referral`: that word is the channel group of any outside site, and a channel of the same name\n * would be impossible to tell apart in queries. */\n 'referral_program',\n] as const;\n\nexport type Channel = (typeof CHANNELS)[number];\n\n/** GA4's default channel groups, as identifiers; a dashboard maps them to display names. */\nexport const CHANNEL_GROUPS = [\n 'direct',\n 'paid_search',\n 'paid_social',\n 'paid_other',\n 'display',\n 'organic_search',\n 'organic_social',\n 'organic_video',\n /** not in GA4's default grouping: sessions an AI assistant sent, by referrer or by ChatGPT's utm */\n 'organic_ai',\n 'referral',\n 'email',\n 'affiliate',\n 'unassigned',\n] as const;\n\nexport type ChannelGroup = (typeof CHANNEL_GROUPS)[number];\n\n/** `utm_source` spellings that mean the same channel: Meta's `{{site_source_name}}` values and the usual synonyms. */\nexport const SOURCE_ALIASES = {\n fb: 'meta',\n ig: 'meta',\n an: 'meta',\n msg: 'meta',\n facebook: 'meta',\n instagram: 'meta',\n bing: 'microsoft',\n twitter: 'x',\n 'google ads': 'google',\n googleads: 'google',\n adwords: 'google',\n 'chatgpt.com': 'chatgpt',\n 'chat.openai.com': 'chatgpt',\n openai: 'chatgpt',\n 'perplexity.ai': 'perplexity',\n 'claude.ai': 'claude',\n 'copilot.com': 'copilot',\n 'deepseek.com': 'deepseek',\n 'doubao.com': 'doubao',\n 'kimi.com': 'kimi',\n} as const satisfies Record<string, Channel>;\n\n/**\n * Which click id belongs to which channel, in priority order. Every key is a field this SDK\n * collects (`AdvertisingInfo`); `fbp` and `rdt_uuid` are deliberately absent — they are pixel\n * browser ids, present with or without a click.\n */\nexport const CLICK_ID_CHANNELS = [\n ['fbclid', 'meta'],\n ['fbc', 'meta'],\n ['gclid', 'google'],\n ['gbraid', 'google'],\n ['wbraid', 'google'],\n ['gad_source', 'google'],\n ['gad_campaignid', 'google'],\n ['dclid', 'dv360'],\n ['msclkid', 'microsoft'],\n ['ttclid', 'tiktok'],\n ['rdt_cid', 'reddit'],\n ['li_fat_id', 'linkedin'],\n ['sccid', 'snapchat'],\n ['twclid', 'x'],\n ['ko_click_id', 'kakao'],\n ['yclid', 'yandex'],\n] as const satisfies readonly (readonly [keyof AdvertisingInfo, Channel])[];\n\n/**\n * A landing page reserved for one channel's ads, for ads that lost their parameters:\n * `/lp/<channel>`, with or without host, query and hash; the capture is the channel. A product\n * that names its landing pages differently replaces this.\n */\nexport const AD_LANDING_PAGE = /^(?:https?:\\/\\/[^/]+)?\\/lp\\/([a-z]+)(?:[/?#]|$)/;\n\nexport type ReferrerMedium = 'organic' | 'social' | 'video' | 'ai';\n\n/**\n * Referrer hosts that name a channel, as regular expressions over the lower-cased host,\n * with the medium GA4 gives that kind of site. Anything else that refers is `referral`, kept as\n * its host. A country TLD is one or two labels (`google.com`, `google.co.uk`, `google.com.hk`),\n * never an open tail, so `google.com.evil.io` is not Google. In match order: the AI assistants\n * first, because `gemini.google.com`, `copilot.microsoft.com` and `yiyan.baidu.com` would\n * otherwise be Google, Microsoft and Baidu search.\n */\nexport const REFERRER_SITES = [\n ['chatgpt', 'ai', /(^|\\.)(chatgpt\\.com|chat\\.openai\\.com)$/],\n ['perplexity', 'ai', /(^|\\.)perplexity\\.ai$/],\n ['gemini', 'ai', /^gemini\\.google\\.com$/],\n ['claude', 'ai', /(^|\\.)claude\\.ai$/],\n ['copilot', 'ai', /^copilot\\.microsoft\\.com$|(^|\\.)copilot\\.com$/],\n ['grok', 'ai', /(^|\\.)(grok\\.com|x\\.ai)$/],\n ['deepseek', 'ai', /(^|\\.)deepseek\\.com$/],\n ['doubao', 'ai', /(^|\\.)doubao\\.com$/],\n ['kimi', 'ai', /(^|\\.)(kimi\\.com|kimi\\.moonshot\\.cn|moonshot\\.cn)$/],\n ['qwen', 'ai', /^tongyi\\.aliyun\\.com$|(^|\\.)(tongyi\\.com|qianwen\\.com|qwen\\.ai)$/],\n ['yuanbao', 'ai', /^yuanbao\\.tencent\\.com$/],\n ['ernie', 'ai', /^yiyan\\.baidu\\.com$|(^|\\.)ernie\\.baidu\\.com$/],\n ['zhipu', 'ai', /(^|\\.)(chatglm\\.cn|zhipuai\\.cn|bigmodel\\.cn)$/],\n ['google', 'organic', /(^|\\.)google\\.[a-z]{2,}(\\.[a-z]{2,3})?$/],\n ['microsoft', 'organic', /(^|\\.)bing\\.com$/],\n ['yahoo', 'organic', /(^|\\.)yahoo\\.[a-z]{2,}(\\.[a-z]{2,3})?$/],\n ['duckduckgo', 'organic', /(^|\\.)duckduckgo\\.com$/],\n ['baidu', 'organic', /(^|\\.)baidu\\.com$/],\n ['yandex', 'organic', /(^|\\.)yandex\\.[a-z]{2,}(\\.[a-z]{2,3})?$/],\n ['ecosia', 'organic', /(^|\\.)ecosia\\.org$/],\n ['naver', 'organic', /(^|\\.)naver\\.com$/],\n ['brave', 'organic', /^search\\.brave\\.com$/],\n ['meta', 'social', /(^|\\.)(facebook\\.com|instagram\\.com|fb\\.com|threads\\.net)$/],\n ['x', 'social', /(^|\\.)(twitter\\.com|x\\.com|t\\.co)$/],\n ['linkedin', 'social', /(^|\\.)(linkedin\\.com|lnkd\\.in)$/],\n ['reddit', 'social', /(^|\\.)reddit\\.com$/],\n ['tiktok', 'social', /(^|\\.)tiktok\\.com$/],\n ['pinterest', 'social', /(^|\\.)pinterest\\.[a-z]{2,}(\\.[a-z]{2,3})?$/],\n ['snapchat', 'social', /(^|\\.)snapchat\\.com$/],\n ['youtube', 'video', /(^|\\.)(youtube\\.com|youtu\\.be)$/],\n] as const satisfies readonly (readonly [Channel, ReferrerMedium, RegExp])[];\n\n/**\n * Referrer hosts that are navigation, not acquisition, when a session happens to start on the way\n * back from them: the local dev host; the payment providers a visitor is bounced through; the\n * sign-in providers whose login lives on a host of its own (Google, Apple, Microsoft, WeChat,\n * Kakao, LINE, Naver, Yahoo, Twitch, X's OAuth 1.0a endpoint); and the hosted auth services a\n * product may sit behind (Auth0, Okta, Supabase, Firebase, Clerk). A product appends its own\n * hostnames — a session that starts from an internal link after the session timeout refers to\n * them. Matched before `REFERRER_SITES`, so `nid.naver.com` and `login.yahoo.com` are not read as\n * a search. Providers whose login shares the host with their content — Facebook, X's OAuth 2.0,\n * LinkedIn, GitHub, Discord — cannot be told apart by host (referrer policies strip the path) and\n * are left as the referrers they usually are. Regular expressions over the lower-cased host.\n */\nexport const REFERRERS_NOT_A_TOUCH = [\n /^localhost(:|$)/,\n // payment\n /(^|\\.)stripe\\.com$/,\n /^pay\\.google\\.com$/,\n /(^|\\.)paypal\\.com$/,\n /(^|\\.)alipay\\.com$/,\n /(^|\\.)paddle\\.com$/,\n /(^|\\.)lemonsqueezy\\.com$/,\n // app stores\n /^apps\\.apple\\.com$/,\n /^play\\.google\\.com$/,\n // sign-in providers with a login host of their own\n /^accounts\\.google\\.com$/,\n /^appleid\\.apple\\.com$/,\n /^login\\.(microsoftonline|live)\\.com$/,\n /^open\\.weixin\\.qq\\.com$/,\n /^(kauth|accounts)\\.kakao\\.com$/,\n /^access\\.line\\.me$/,\n /^nid\\.naver\\.com$/,\n /^login\\.yahoo\\.com$/,\n /^id\\.twitch\\.tv$/,\n /^api\\.twitter\\.com$/,\n // hosted auth services\n /(^|\\.)auth0\\.com$/,\n /(^|\\.)okta\\.com$/,\n /(^|\\.)supabase\\.co$/,\n /(^|\\.)firebaseapp\\.com$/,\n /(^|\\.)clerk\\.accounts\\.dev$/,\n] as const;\n\n/** GA4's paid mediums — cpc, cpm, ppc, retargeting, paid_social, … — plus Performance Max. */\nexport const PAID_MEDIUM = /^(.*cp.*|ppc|retargeting|paid.*|pmax|performance_max)$/;\n/**\n * Meta's `{{placement}}` values, lower-cased, which an ad URL template of `utm_medium={{placement}}`\n * puts in the medium. Only an ad carries one — an organic post arrives as a referrer, with no utm\n * at all — so a medium in this list is a paid Meta click whatever the source says (a template with\n * `utm_source=meta-websitekeyinfo` was seen). Listed one by one rather than matched by prefix, so\n * that a hand-tagged `instagram_stories` post cannot be mistaken for an ad only because of how it\n * is spelled … which means a placement Meta adds later shows up as unassigned until it is added\n * here. Meta's documented values plus the ones seen in the wild (`facebook_mobile_reels`,\n * `facebook_notification`, `an`), and the literal macro for a template that did not expand it.\n */\nexport const META_PLACEMENTS = [\n 'facebook_desktop_feed',\n 'facebook_mobile_feed',\n 'facebook_mobile_reels',\n 'facebook_reels',\n 'facebook_reels_overlay',\n 'facebook_right_column',\n 'facebook_marketplace',\n 'facebook_video_feeds',\n 'facebook_stories',\n 'facebook_search',\n 'facebook_instream_video',\n 'facebook_instant_article',\n 'facebook_groups_feed',\n 'facebook_profile_feed',\n 'facebook_notification',\n 'facebook_notifications',\n 'facebook_business_explore',\n 'instagram_feed',\n 'instagram_stories',\n 'instagram_reels',\n 'instagram_reels_overlay',\n 'instagram_explore',\n 'instagram_explore_home',\n 'instagram_search',\n 'instagram_shop',\n 'instagram_profile_feed',\n 'instagram_profile_reels',\n 'instagram_igtv',\n 'messenger_inbox',\n 'messenger_stories',\n 'messenger_sponsored_messages',\n 'threads_feed',\n 'whatsapp_status',\n 'audience_network_classic',\n 'audience_network_rewarded_video',\n 'audience_network_native_banner_and_interstitial',\n 'an',\n 'others',\n /** the macro itself, when Meta did not expand it (written in a field it does not substitute, or a\n * preview click): still only ever produced by a Meta ad URL, so still a paid Meta click */\n '{{placement}}',\n] as const;\nexport const DISPLAY_MEDIUMS = ['display', 'banner', 'expandable', 'interstitial'] as const;\n/** GA4's email spellings, as a source or a medium. */\nexport const EMAIL_MEDIUMS = ['email', 'e-mail', 'e_mail', 'e mail'] as const;\n/** A medium that says email or newsletter anywhere in it: `outbound email`, `cold_email`, `newsletter`, and GA4's four. */\nexport const EMAIL_MEDIUM = /(^|[^a-z])(e[-_ ]?mail|newsletter)([^a-z]|$)/;\n\n/** Where a touch came from: a tracked session, or a report by the user or staff. */\nexport const TOUCH_SOURCES = ['tracked', 'reported'] as const;\nexport type TouchSource = (typeof TOUCH_SOURCES)[number];\n\n/**\n * How a reported touch was learned:\n * - survey: the user answered \"how did you hear about us\" (onboarding, checkout)\n * - promo_code: the user redeemed a code that belongs to a channel\n * - phone: a call came in on a channel's dedicated number, marked by staff or the phone system\n * - manual: staff recorded what a customer told them\n */\nexport const REPORTED_TOUCH_KINDS = ['survey', 'promo_code', 'phone', 'manual'] as const;\nexport type ReportedTouchKind = (typeof REPORTED_TOUCH_KINDS)[number];\n\n/**\n * How much a touch is worth against another when attribution has to choose between sessions;\n * lower wins, and the latest wins among equals. Stored on the session when it is classified, so\n * renumbering means reclassifying.\n *\n * This ranks touches against each other. Within one session the rules that name its channel have\n * their own order — `utm_source`, then a click id, then the ad landing page, then the referrer —\n * and the first that says something wins; the session's priority is then the tier of that rule.\n * So two sessions tagged with utm and gclid respectively are equal here (both `campaign`) and the\n * later one is credited, while one session carrying both is named by its utm.\n */\nexport const TOUCH_PRIORITY = {\n /** utm, click id, ad landing page: someone tagged that link (in that order within a session) */\n campaign: 1,\n /** a reported touch staff stand behind: a call on a channel's number, a recorded conversation */\n verified: 1,\n /** the browser said where the visitor came from; nobody chose it */\n referrer: 2,\n /** a reported touch that is the user's claim: a survey answer, a code that may have been shared */\n claimed: 3,\n} as const satisfies Record<string, number>;\n\n/** Which reported kinds are staff facts and which are the user's claims. */\nexport const REPORTED_TOUCH_PRIORITY = {\n phone: TOUCH_PRIORITY.verified,\n manual: TOUCH_PRIORITY.verified,\n survey: TOUCH_PRIORITY.claimed,\n promo_code: TOUCH_PRIORITY.claimed,\n} as const satisfies Record<ReportedTouchKind, number>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"vocabulary.mjs","names":[],"sources":["../../src/attribution/vocabulary.ts"],"sourcesContent":["import type { AdvertisingInfo } from '../track/types';\n\n/**\n * The vocabulary attribution is built from, shared by every product's `session` table and by the\n * dashboards that read it. Data for `classifyTouch` (./classify), which turns it into a channel;\n * a product's dashboards read the same names back. What stays with the product is its own hostnames\n * (referrer exclusions) and its landing-page conventions.\n */\n\n/** A session that arrived through nothing we can name. GA's spelling, so dashboards read as GA. */\nexport const DIRECT_CHANNEL = '(direct)';\n/** The medium of a direct session. */\nexport const NO_MEDIUM = '(none)';\n/** The medium of a tagged link that named a source but no medium. */\nexport const MEDIUM_NOT_SET = '(not set)';\n\n/** The channels the rules below can name. A `utm_source` outside this list is its own channel. */\nexport const CHANNELS = [\n 'meta',\n 'google',\n 'dv360',\n 'microsoft',\n 'tiktok',\n 'reddit',\n 'linkedin',\n 'snapchat',\n 'x',\n 'kakao',\n 'yandex',\n 'yahoo',\n 'duckduckgo',\n 'baidu',\n 'ecosia',\n 'naver',\n 'brave',\n 'pinterest',\n 'youtube',\n /** AI assistants that send people to sites: ChatGPT tags its links `utm_source=chatgpt.com`, the\n * others show as a referrer. Their own channel group, `organic_ai`, since GA4's default groups\n * would file them under Referral / Unassigned and the question \"how much does AI bring\" comes up. */\n 'chatgpt',\n 'perplexity',\n 'gemini',\n 'claude',\n 'copilot',\n 'grok',\n /** and the Chinese ones — DeepSeek, 豆包, Kimi, 通义, 腾讯元宝, 文心一言, 智谱清言 */\n 'deepseek',\n 'doubao',\n 'kimi',\n 'qwen',\n 'yuanbao',\n 'ernie',\n 'zhipu',\n /** the product's own referral programme: the session came through a member's link or code.\n * How a product recognises one (a `/refer/<code>` path, a code at sign-up) is its own rule. Not\n * `referral`: that word is the channel group of any outside site, and a channel of the same name\n * would be impossible to tell apart in queries. */\n 'referral_program',\n] as const;\n\nexport type Channel = (typeof CHANNELS)[number];\n\n/** GA4's default channel groups, as identifiers; a dashboard maps them to display names. */\nexport const CHANNEL_GROUPS = [\n 'direct',\n 'paid_search',\n 'paid_social',\n 'paid_other',\n 'display',\n 'organic_search',\n 'organic_social',\n 'organic_video',\n /** not in GA4's default grouping: sessions an AI assistant sent, by referrer or by ChatGPT's utm */\n 'organic_ai',\n 'referral',\n 'email',\n 'affiliate',\n 'unassigned',\n] as const;\n\nexport type ChannelGroup = (typeof CHANNEL_GROUPS)[number];\n\n/** `utm_source` spellings that mean the same channel: Meta's `{{site_source_name}}` values and the usual synonyms. */\nexport const SOURCE_ALIASES = {\n fb: 'meta',\n ig: 'meta',\n an: 'meta',\n msg: 'meta',\n th: 'meta',\n facebook: 'meta',\n instagram: 'meta',\n bing: 'microsoft',\n twitter: 'x',\n 'google ads': 'google',\n googleads: 'google',\n adwords: 'google',\n 'chatgpt.com': 'chatgpt',\n 'chat.openai.com': 'chatgpt',\n openai: 'chatgpt',\n 'perplexity.ai': 'perplexity',\n 'claude.ai': 'claude',\n 'copilot.com': 'copilot',\n 'deepseek.com': 'deepseek',\n 'doubao.com': 'doubao',\n 'kimi.com': 'kimi',\n} as const satisfies Record<string, Channel>;\n\n/**\n * Which click id belongs to which channel, in priority order, and whether the platform puts it on\n * its ad clicks only (`'ads'`) or on other links as well (`'any'`). Every key is a field this SDK\n * collects (`AdvertisingInfo`).\n *\n * The third column decides whether the id can say a click was paid when a `utm_source` names the\n * channel but no `utm_medium` says how (a Reddit ad tagged `utm_source=reddit` and nothing more).\n * `fbclid` is `'any'`: Meta decorates every outbound link with it, organic posts, profile links\n * and shares included. `twclid` and `ko_click_id` are `'any'` until it is clear they never\n * decorate an organic link.\n *\n * Deliberately absent: `fbp` and `rdt_uuid`, pixel browser ids present with or without a click;\n * and `fbc`, which the SDK only ever reads from the `_fbc` cookie. That cookie lives 90 days after\n * a Meta click, so counting it named every later visit — typed in, from search, from an email — a\n * new Meta click. `fbclid` is read from the landing URL only, so it is this visit's click.\n */\nexport const CLICK_ID_CHANNELS = [\n ['fbclid', 'meta', 'any'],\n ['gclid', 'google', 'ads'],\n ['gbraid', 'google', 'ads'],\n ['wbraid', 'google', 'ads'],\n ['gad_source', 'google', 'ads'],\n ['gad_campaignid', 'google', 'ads'],\n ['dclid', 'dv360', 'ads'],\n ['msclkid', 'microsoft', 'ads'],\n ['ttclid', 'tiktok', 'ads'],\n ['rdt_cid', 'reddit', 'ads'],\n ['li_fat_id', 'linkedin', 'ads'],\n ['ScCid', 'snapchat', 'ads'],\n ['twclid', 'x', 'any'],\n ['ko_click_id', 'kakao', 'any'],\n ['yclid', 'yandex', 'ads'],\n ['oppref', 'chatgpt', 'ads'],\n ['epik', 'pinterest', 'ads'],\n] as const satisfies readonly (readonly [keyof AdvertisingInfo, Channel, 'ads' | 'any'])[];\n\n/**\n * A landing page reserved for one channel's ads, for ads that lost their parameters:\n * `/lp/<channel>`, with or without host, query and hash; the capture is the channel. A product\n * that names its landing pages differently replaces this.\n */\nexport const AD_LANDING_PAGE = /^(?:https?:\\/\\/[^/]+)?\\/lp\\/([a-z]+)(?:[/?#]|$)/;\n\nexport type ReferrerMedium = 'organic' | 'social' | 'video' | 'ai';\n\n/**\n * Referrer hosts that name a channel, as regular expressions over the lower-cased host,\n * with the medium GA4 gives that kind of site. Anything else that refers is `referral`, kept as\n * its host. A country TLD is one or two labels (`google.com`, `google.co.uk`, `google.com.hk`),\n * never an open tail, so `google.com.evil.io` is not Google. In match order: the AI assistants\n * first, because `gemini.google.com`, `copilot.microsoft.com` and `yiyan.baidu.com` would\n * otherwise be Google, Microsoft and Baidu search.\n */\nexport const REFERRER_SITES = [\n ['chatgpt', 'ai', /(^|\\.)(chatgpt\\.com|chat\\.openai\\.com)$/],\n ['perplexity', 'ai', /(^|\\.)perplexity\\.ai$/],\n ['gemini', 'ai', /^gemini\\.google\\.com$/],\n ['claude', 'ai', /(^|\\.)claude\\.ai$/],\n ['copilot', 'ai', /^copilot\\.microsoft\\.com$|(^|\\.)copilot\\.com$/],\n ['grok', 'ai', /(^|\\.)(grok\\.com|x\\.ai)$/],\n ['deepseek', 'ai', /(^|\\.)deepseek\\.com$/],\n ['doubao', 'ai', /(^|\\.)doubao\\.com$/],\n ['kimi', 'ai', /(^|\\.)(kimi\\.com|kimi\\.moonshot\\.cn|moonshot\\.cn)$/],\n ['qwen', 'ai', /^tongyi\\.aliyun\\.com$|(^|\\.)(tongyi\\.com|qianwen\\.com|qwen\\.ai)$/],\n ['yuanbao', 'ai', /^yuanbao\\.tencent\\.com$/],\n ['ernie', 'ai', /^yiyan\\.baidu\\.com$|(^|\\.)ernie\\.baidu\\.com$/],\n ['zhipu', 'ai', /(^|\\.)(chatglm\\.cn|zhipuai\\.cn|bigmodel\\.cn)$/],\n ['google', 'organic', /(^|\\.)google\\.[a-z]{2,}(\\.[a-z]{2,3})?$/],\n ['microsoft', 'organic', /(^|\\.)bing\\.com$/],\n ['yahoo', 'organic', /(^|\\.)yahoo\\.[a-z]{2,}(\\.[a-z]{2,3})?$/],\n ['duckduckgo', 'organic', /(^|\\.)duckduckgo\\.com$/],\n ['baidu', 'organic', /(^|\\.)baidu\\.com$/],\n ['yandex', 'organic', /(^|\\.)yandex\\.[a-z]{2,}(\\.[a-z]{2,3})?$/],\n ['ecosia', 'organic', /(^|\\.)ecosia\\.org$/],\n ['naver', 'organic', /(^|\\.)naver\\.com$/],\n ['brave', 'organic', /^search\\.brave\\.com$/],\n ['meta', 'social', /(^|\\.)(facebook\\.com|instagram\\.com|fb\\.com|threads\\.net)$/],\n ['x', 'social', /(^|\\.)(twitter\\.com|x\\.com|t\\.co)$/],\n ['linkedin', 'social', /(^|\\.)(linkedin\\.com|lnkd\\.in)$/],\n ['reddit', 'social', /(^|\\.)reddit\\.com$/],\n ['tiktok', 'social', /(^|\\.)tiktok\\.com$/],\n ['pinterest', 'social', /(^|\\.)pinterest\\.[a-z]{2,}(\\.[a-z]{2,3})?$/],\n ['snapchat', 'social', /(^|\\.)snapchat\\.com$/],\n ['youtube', 'video', /(^|\\.)(youtube\\.com|youtu\\.be)$/],\n] as const satisfies readonly (readonly [Channel, ReferrerMedium, RegExp])[];\n\n/**\n * Referrer hosts that are navigation, not acquisition, when a session happens to start on the way\n * back from them: the local dev host; the payment providers a visitor is bounced through; the\n * sign-in providers whose login lives on a host of its own (Google, Apple, Microsoft, WeChat,\n * Kakao, LINE, Naver, Yahoo, Twitch, X's OAuth 1.0a endpoint); and the hosted auth services a\n * product may sit behind (Auth0, Okta, Supabase, Firebase, Clerk). A product appends its own\n * hostnames — a session that starts from an internal link after the session timeout refers to\n * them. Matched before `REFERRER_SITES`, so `nid.naver.com` and `login.yahoo.com` are not read as\n * a search. Providers whose login shares the host with their content — Facebook, X's OAuth 2.0,\n * LinkedIn, GitHub, Discord — cannot be told apart by host (referrer policies strip the path) and\n * are left as the referrers they usually are. Regular expressions over the lower-cased host.\n */\nexport const REFERRERS_NOT_A_TOUCH = [\n /^localhost(:|$)/,\n // payment\n /(^|\\.)stripe\\.com$/,\n /^pay\\.google\\.com$/,\n /(^|\\.)paypal\\.com$/,\n /(^|\\.)alipay\\.com$/,\n /(^|\\.)paddle\\.com$/,\n /(^|\\.)lemonsqueezy\\.com$/,\n // app stores\n /^apps\\.apple\\.com$/,\n /^play\\.google\\.com$/,\n // sign-in providers with a login host of their own\n /^accounts\\.google\\.com$/,\n /^appleid\\.apple\\.com$/,\n /^login\\.(microsoftonline|live)\\.com$/,\n /^open\\.weixin\\.qq\\.com$/,\n /^(kauth|accounts)\\.kakao\\.com$/,\n /^access\\.line\\.me$/,\n /^nid\\.naver\\.com$/,\n /^login\\.yahoo\\.com$/,\n /^id\\.twitch\\.tv$/,\n /^api\\.twitter\\.com$/,\n // hosted auth services\n /(^|\\.)auth0\\.com$/,\n /(^|\\.)okta\\.com$/,\n /(^|\\.)supabase\\.co$/,\n /(^|\\.)firebaseapp\\.com$/,\n /(^|\\.)clerk\\.accounts\\.dev$/,\n] as const;\n\n/** GA4's paid mediums — cpc, cpm, ppc, retargeting, paid_social, … — plus Performance Max. */\nexport const PAID_MEDIUM = /^(.*cp.*|ppc|retargeting|paid.*|pmax|performance_max)$/;\n/**\n * Meta's `{{placement}}` values, lower-cased, which an ad URL template of `utm_medium={{placement}}`\n * puts in the medium. Only an ad carries one — an organic post arrives as a referrer, with no utm\n * at all — so a medium in this list is a paid Meta click whatever the source says (a template with\n * `utm_source=meta-websitekeyinfo` was seen). Listed one by one rather than matched by prefix, so\n * that a hand-tagged `instagram_stories` post cannot be mistaken for an ad only because of how it\n * is spelled … which means a placement Meta adds later shows up as unassigned until it is added\n * here. Meta's documented values plus the ones seen in the wild (`facebook_mobile_reels`,\n * `facebook_notification`, `an`), and the literal macro for a template that did not expand it.\n */\nexport const META_PLACEMENTS = [\n 'facebook_desktop_feed',\n 'facebook_mobile_feed',\n 'facebook_mobile_reels',\n 'facebook_reels',\n 'facebook_reels_overlay',\n 'facebook_right_column',\n 'facebook_marketplace',\n 'facebook_video_feeds',\n 'facebook_stories',\n 'facebook_search',\n 'facebook_instream_video',\n 'facebook_instant_article',\n 'facebook_groups_feed',\n 'facebook_profile_feed',\n 'facebook_notification',\n 'facebook_notifications',\n 'facebook_business_explore',\n 'instagram_feed',\n 'instagram_stories',\n 'instagram_reels',\n 'instagram_reels_overlay',\n 'instagram_explore',\n 'instagram_explore_home',\n 'instagram_search',\n 'instagram_shop',\n 'instagram_profile_feed',\n 'instagram_profile_reels',\n 'instagram_igtv',\n 'messenger_inbox',\n 'messenger_stories',\n 'messenger_sponsored_messages',\n 'threads_feed',\n 'whatsapp_status',\n 'audience_network_classic',\n 'audience_network_rewarded_video',\n 'audience_network_native_banner_and_interstitial',\n 'an',\n 'others',\n /** the macro itself, when Meta did not expand it (written in a field it does not substitute, or a\n * preview click): still only ever produced by a Meta ad URL, so still a paid Meta click */\n '{{placement}}',\n] as const;\nexport const DISPLAY_MEDIUMS = ['display', 'banner', 'expandable', 'interstitial'] as const;\n/** GA4's email spellings, as a source or a medium. */\nexport const EMAIL_MEDIUMS = ['email', 'e-mail', 'e_mail', 'e mail'] as const;\n/** A medium that says email or newsletter anywhere in it: `outbound email`, `cold_email`, `newsletter`, and GA4's four. */\nexport const EMAIL_MEDIUM = /(^|[^a-z])(e[-_ ]?mail|newsletter)([^a-z]|$)/;\n\n/** Where a touch came from: a tracked session, or a report by the user or staff. */\nexport const TOUCH_SOURCES = ['tracked', 'reported'] as const;\nexport type TouchSource = (typeof TOUCH_SOURCES)[number];\n\n/**\n * How a reported touch was learned:\n * - survey: the user answered \"how did you hear about us\" (onboarding, checkout)\n * - promo_code: the user redeemed a code that belongs to a channel\n * - phone: a call came in on a channel's dedicated number, marked by staff or the phone system\n * - manual: staff recorded what a customer told them\n */\nexport const REPORTED_TOUCH_KINDS = ['survey', 'promo_code', 'phone', 'manual'] as const;\nexport type ReportedTouchKind = (typeof REPORTED_TOUCH_KINDS)[number];\n\n/**\n * How much a touch is worth against another when attribution has to choose between sessions;\n * lower wins, and the latest wins among equals. Stored on the session when it is classified, so\n * renumbering means reclassifying.\n *\n * This ranks touches against each other. Within one session the rules that name its channel have\n * their own order — `utm_source`, then a click id, then the ad landing page, then the referrer —\n * and the first that says something wins; the session's priority is then the tier of that rule.\n * So two sessions tagged with utm and gclid respectively are equal here (both `campaign`) and the\n * later one is credited, while one session carrying both is named by its utm.\n */\nexport const TOUCH_PRIORITY = {\n /** utm, click id, ad landing page: someone tagged that link (in that order within a session) */\n campaign: 1,\n /** a reported touch staff stand behind: a call on a channel's number, a recorded conversation */\n verified: 1,\n /** the browser said where the visitor came from; nobody chose it */\n referrer: 2,\n /** a reported touch that is the user's claim: a survey answer, a code that may have been shared */\n claimed: 3,\n} as const satisfies Record<string, number>;\n\n/** Which reported kinds are staff facts and which are the user's claims. */\nexport const REPORTED_TOUCH_PRIORITY = {\n phone: TOUCH_PRIORITY.verified,\n manual: TOUCH_PRIORITY.verified,\n survey: TOUCH_PRIORITY.claimed,\n promo_code: TOUCH_PRIORITY.claimed,\n} as const satisfies Record<ReportedTouchKind, number>;\n"],"mappings":"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"}
@@ -107,12 +107,14 @@ const tagsSchema = (0, zod_mini.object)({
107
107
  ko_click_id: (0, zod_mini.optional)((0, zod_mini.string)()),
108
108
  li_fat_id: (0, zod_mini.optional)((0, zod_mini.string)()),
109
109
  msclkid: (0, zod_mini.optional)((0, zod_mini.string)()),
110
- sccid: (0, zod_mini.optional)((0, zod_mini.string)()),
110
+ ScCid: (0, zod_mini.optional)((0, zod_mini.string)()),
111
111
  ttclid: (0, zod_mini.optional)((0, zod_mini.string)()),
112
112
  twclid: (0, zod_mini.optional)((0, zod_mini.string)()),
113
113
  wbraid: (0, zod_mini.optional)((0, zod_mini.string)()),
114
114
  gbraid: (0, zod_mini.optional)((0, zod_mini.string)()),
115
115
  yclid: (0, zod_mini.optional)((0, zod_mini.string)()),
116
+ oppref: (0, zod_mini.optional)((0, zod_mini.string)()),
117
+ epik: (0, zod_mini.optional)((0, zod_mini.string)()),
116
118
  utm_source: (0, zod_mini.optional)((0, zod_mini.string)()),
117
119
  utm_medium: (0, zod_mini.optional)((0, zod_mini.string)()),
118
120
  utm_campaign: (0, zod_mini.optional)((0, zod_mini.string)()),
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["pipe","string","transform","array","record","union","number","boolean","_null","object","optional","trim","minLength","maxLength","regex","uuid","_enum","iso","toLowerCase","email","e164","toUpperCase","url"],"sources":["../../src/schema/index.ts"],"sourcesContent":["import {\n enum as _enum,\n null as _null,\n array,\n boolean,\n e164,\n email,\n iso,\n maxLength,\n minLength,\n number,\n object,\n optional,\n pipe,\n record,\n regex,\n string,\n toLowerCase,\n toUpperCase,\n transform,\n trim,\n union,\n url,\n uuid,\n type z,\n} from 'zod/mini';\nimport type { Environment, Platform } from '../track/types';\n\nconst MAX_KEY_LENGTH = 128;\nconst MAX_VALUE_LENGTH = 512;\nconst MAX_PROPERTIES = 64;\n\n/**\n * Truncated rather than rejected. These schemas validate a whole batch at once, so refusing one\n * oversized value costs every event that traveled with it — and the values that overrun are the\n * ones derived from the page (a link's text, a URL carrying a long query), which no client can\n * bound in advance. A shortened value is worth more than a lost batch.\n */\nconst propertyText = pipe(\n string(),\n transform((value) => value.slice(0, MAX_VALUE_LENGTH))\n);\n\n/**\n * Keys are written by hand in instrumentation code, so an unusable one is a mistake in the host\n * rather than something the visitor typed. It is still dropped rather than rejected, for the same\n * reason: the mistake should cost that property, not the batch it happens to be in. Truncating a\n * key is not an option — two long keys would silently become one field.\n *\n * The key schema below is deliberately permissive so that this transform is reached at all; the\n * trimming it used to do happens here instead. `MAX_PROPERTIES` keeps the first N in insertion\n * order.\n */\nfunction takeProperties<T>(data: Record<string, T>): Record<string, T> {\n const result: Record<string, T> = {};\n let count = 0;\n for (const [rawKey, value] of Object.entries(data)) {\n if (count >= MAX_PROPERTIES) break;\n const key = rawKey.trim();\n if (!key || key.length > MAX_KEY_LENGTH) continue;\n result[key] = value;\n count++;\n }\n return result;\n}\n\n/**\n * Capped at GA4's own item-list limit, and truncated rather than rejected like every other\n * property limit here: an unbounded array is the one field a caller could still blow a batch\n * up with after the value and key limits.\n */\nconst MAX_ITEMS = 200;\n\nconst items = pipe(\n array(\n pipe(\n record(string(), union([propertyText, number(), boolean(), _null()])),\n transform(takeProperties)\n )\n ),\n transform((list) => list.slice(0, MAX_ITEMS))\n);\n\nexport const ALL_PLATFORMS = [\n 'ios',\n 'android',\n 'web',\n 'macos',\n 'windows',\n 'linux',\n 'unknown',\n] as const satisfies Platform[];\n\nexport const ALL_ENVIRONMENTS = ['development', 'production'] as const satisfies Environment[];\n\nexport const tagsSchema = object({\n os: optional(string()),\n os_name: optional(string()),\n os_version: optional(string()),\n browser: optional(string()),\n browser_name: optional(string()),\n browser_version: optional(string()),\n device: optional(string()),\n device_id: optional(string().check(trim(), minLength(1), maxLength(36))),\n device_type: optional(string()),\n device_vendor: optional(string()),\n device_pixel_ratio: optional(number()),\n screen_width: optional(number()),\n screen_height: optional(number()),\n screen_resolution: optional(\n pipe(\n string().check(regex(/^\\d+x\\d+$/)),\n transform((v) => v as `${number}x${number}`)\n )\n ),\n webdriver: optional(boolean()),\n release: optional(string()),\n language: optional(string()),\n time_zone: optional(string()),\n page_location: optional(string()),\n page_referrer: optional(string()),\n page_title: optional(string()),\n page_load_id: optional(string()),\n /**\n * @deprecated Renamed to `page_location` in 7.0.0. Accepted so that events from clients\n * still on an older SDK are not stripped of their page URL at this boundary — a browser\n * bundle stays cached long after a backend deploys. Remove once those clients are gone;\n * `pageLocation` in `server/page-location.ts` is the only reader.\n */\n source_url: optional(string()),\n // app info\n advertising_id: optional(string()),\n install_referrer: optional(string()),\n // Meta Ads\n fbc: optional(string()),\n fbp: optional(string()),\n fbclid: optional(string()),\n ad_id: optional(string()),\n ad_name: optional(string()),\n adset_id: optional(string()),\n adset_name: optional(string()),\n campaign_id: optional(string()),\n campaign_name: optional(string()),\n placement: optional(string()),\n // Google Ads\n gclid: optional(string()),\n gclsrc: optional(string()),\n gad_source: optional(string()),\n gad_campaignid: optional(string()),\n // Reddit ads\n rdt_cid: optional(string()),\n rdt_uuid: optional(string()),\n // click ids\n dclid: optional(string()),\n ko_click_id: optional(string()),\n li_fat_id: optional(string()),\n msclkid: optional(string()),\n sccid: optional(string()),\n ttclid: optional(string()),\n twclid: optional(string()),\n wbraid: optional(string()),\n gbraid: optional(string()),\n yclid: optional(string()),\n // utm params\n utm_source: optional(string()),\n utm_medium: optional(string()),\n utm_campaign: optional(string()),\n utm_term: optional(string()),\n utm_content: optional(string()),\n utm_id: optional(string()),\n utm_source_platform: optional(string()),\n utm_creative_format: optional(string()),\n utm_marketing_tactic: optional(string()),\n});\n\nexport const propertiesSchema = optional(\n pipe(\n record(string(), union([propertyText, number(), boolean(), _null(), items])),\n transform(takeProperties)\n )\n);\n\n/** Visitor properties differ from event properties only in taking no nested item lists. */\nconst visitorPropertiesSchema = optional(\n pipe(\n record(string(), union([propertyText, number(), boolean(), _null()])),\n transform(takeProperties)\n )\n);\n\n/**\n * How far an event's time may be from the server's before the client clock it was stamped with is\n * taken as wrong. A batch legitimately arrives late — a tab frozen in the background, a\n * session_start held back after a failed batch — by hours, not days; a phone set to another year\n * writes its sessions into that year.\n */\nconst MAX_CLOCK_SKEW = 24 * 60 * 60 * 1000;\n\n/**\n * Puts the events stamped by a wrong client clock onto the server's, where they are parsed. Only\n * the events outside `MAX_CLOCK_SKEW` move, so one bad event cannot drag the rest of its batch\n * along: they move together by their own latest one — the wrong clock at sending — keeping their\n * order and spacing, and one still out after that (a batch mixing two wrong clocks) is on no clock\n * at all and takes the server's time. Corrected rather than rejected, for the same reason values\n * are truncated: a wrong clock should cost the event its time, not the batch its events.\n */\nfunction alignClock<T extends { timestamp: string }>(events: T[], now = Date.now()): T[] {\n const within = (time: number) => Math.abs(now - time) <= MAX_CLOCK_SKEW;\n const times = events.map((event) => Date.parse(event.timestamp));\n const wrong = times.filter((time) => !within(time));\n if (wrong.length === 0) return events;\n const offset = now - Math.max(...wrong);\n return events.map((event, i) => {\n if (within(times[i])) return event;\n const shifted = times[i] + offset;\n return { ...event, timestamp: new Date(within(shifted) ? shifted : now).toISOString() };\n });\n}\n\nexport const createTrackEventSchema = pipe(\n array(\n object({\n name: string().check(trim(), minLength(1), maxLength(64)),\n visitor_id: uuid(),\n session_id: uuid(),\n platform: _enum(ALL_PLATFORMS),\n environment: _enum(ALL_ENVIRONMENTS),\n timestamp: iso.datetime(),\n tags: tagsSchema,\n properties: propertiesSchema,\n })\n ).check(minLength(1), maxLength(100)),\n transform((events) => alignClock(events))\n);\n\nexport const createVisitorSchema = object({\n device_id: string().check(trim(), minLength(1), maxLength(36)),\n platform: _enum(ALL_PLATFORMS),\n environment: _enum(ALL_ENVIRONMENTS),\n tags: tagsSchema,\n properties: visitorPropertiesSchema,\n});\n\nconst emailValue = pipe(string().check(trim(), toLowerCase(), maxLength(320)), email());\n\n/** E.164: a plus sign (+) prefix, country code, then digits only, no dashes/parens/spaces. */\nconst phoneValue = pipe(string().check(trim()), e164());\n\nconst addressValue = object({\n first_name: optional(string().check(trim(), maxLength(128))),\n last_name: optional(string().check(trim(), maxLength(128))),\n street: optional(string().check(trim(), maxLength(256))),\n city: optional(string().check(trim(), maxLength(128))),\n /** User province, state, or region. Example: `Hampshire` */\n region: optional(string().check(trim(), maxLength(128))),\n postal_code: optional(string().check(trim(), maxLength(32))),\n /** 2-letter country code, per the ISO 3166-1 alpha-2 standard. Example: `UK` */\n country: optional(string().check(trim(), toUpperCase(), regex(/^[A-Z]{2}$/))),\n});\n\n/**\n * User-provided data (UPD) used for enhanced conversions, Customer Match, and demographics.\n * Values are sent unhashed; Google normalizes and hashes them before they reach its servers.\n *\n * Multiple values may be sent to increase the match rate: up to 3 emails, 3 phone numbers, and\n * 2 addresses.\n *\n * @see https://support.google.com/analytics/answer/14078702\n * @see https://support.google.com/google-ads/answer/13258081\n */\nexport const userProvidedDataSchema = object({\n email: optional(union([emailValue, array(emailValue).check(minLength(1), maxLength(3))])),\n phone_number: optional(union([phoneValue, array(phoneValue).check(minLength(1), maxLength(3))])),\n address: optional(union([addressValue, array(addressValue).check(minLength(1), maxLength(2))])),\n});\n\nexport const updateVisitorSchema = object({\n user_id: optional(uuid()),\n user_data: optional(userProvidedDataSchema),\n tags: tagsSchema,\n properties: visitorPropertiesSchema,\n});\n\nexport const createFeedbackSchema = object({\n name: string().check(minLength(1), maxLength(256)),\n email: email().check(maxLength(320)),\n message: string().check(minLength(1), maxLength(65536)),\n});\n\nconst noEmptyString = pipe(\n string().check(maxLength(256)),\n transform((v) => (v ? v : undefined))\n);\n\n/**\n * The schema for creating a link.\n * @see https://support.google.com/analytics/answer/10917952\n * */\nexport const createLinkSchema = object({\n /** The URL that the user is redirected to. */\n url: url().check(minLength(1), maxLength(1024)), // required\n\n /**\n * Campaign ID. Used to identify a specific campaign or promotion. This is a required key for GA4\n * data import. Use the same IDs that you use when uploading campaign cost data.\n */\n utm_id: optional(noEmptyString),\n\n /** Referrer, for example: google, newsletter4, billboard */\n utm_source: string().check(minLength(1), maxLength(256)), // required\n\n /** Marketing medium, for example: cpc, banner, email */\n utm_medium: string().check(minLength(1), maxLength(256)), // required\n\n /** Product, slogan, promo code, for example, spring_sale */\n utm_campaign: string().check(minLength(1), maxLength(256)), // required\n\n /** Paid keyword */\n utm_term: optional(noEmptyString),\n\n /**\n * Use to differentiate creatives. For example, if you have two call-to-action links within the\n * same email message, you can use utm_content and set different values for each so you can tell\n * which version is more effective.\n */\n utm_content: optional(noEmptyString),\n\n /**\n * The platform responsible for directing traffic to a given Analytics property (such as a buying\n * platform that sets budgets and targeting criteria or a platform that manages organic traffic\n * data). For example, Search Ads 360 or Display & Video 360.\n */\n utm_source_platform: optional(noEmptyString),\n\n /**\n * Type of creative, for example, display, native, video, search, utm_creative_format is not\n * currently reported in Google Analytics 4 properties.\n */\n utm_creative_format: optional(noEmptyString),\n\n /**\n * Targeting criteria applied to a campaign, for example, remarketing, prospecting,\n * utm_marketing_tactic is not currently reported in Google Analytics 4 properties.\n * */\n utm_marketing_tactic: optional(noEmptyString),\n});\n\nexport type CreateTrackEventDTO = z.output<typeof createTrackEventSchema>;\nexport type CreateFeedbackDTO = z.output<typeof createFeedbackSchema>;\nexport type CreateLinkDTO = z.output<typeof createLinkSchema>;\nexport type CreateVisitorDTO = z.output<typeof createVisitorSchema>;\nexport type UserProvidedDataDTO = z.output<typeof userProvidedDataSchema>;\nexport type UpdateVisitorDTO = z.output<typeof updateVisitorSchema>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["pipe","string","transform","array","record","union","number","boolean","_null","object","optional","trim","minLength","maxLength","regex","uuid","_enum","iso","toLowerCase","email","e164","toUpperCase","url"],"sources":["../../src/schema/index.ts"],"sourcesContent":["import {\n enum as _enum,\n null as _null,\n array,\n boolean,\n e164,\n email,\n iso,\n maxLength,\n minLength,\n number,\n object,\n optional,\n pipe,\n record,\n regex,\n string,\n toLowerCase,\n toUpperCase,\n transform,\n trim,\n union,\n url,\n uuid,\n type z,\n} from 'zod/mini';\nimport type { Environment, Platform } from '../track/types';\n\nconst MAX_KEY_LENGTH = 128;\nconst MAX_VALUE_LENGTH = 512;\nconst MAX_PROPERTIES = 64;\n\n/**\n * Truncated rather than rejected. These schemas validate a whole batch at once, so refusing one\n * oversized value costs every event that traveled with it — and the values that overrun are the\n * ones derived from the page (a link's text, a URL carrying a long query), which no client can\n * bound in advance. A shortened value is worth more than a lost batch.\n */\nconst propertyText = pipe(\n string(),\n transform((value) => value.slice(0, MAX_VALUE_LENGTH))\n);\n\n/**\n * Keys are written by hand in instrumentation code, so an unusable one is a mistake in the host\n * rather than something the visitor typed. It is still dropped rather than rejected, for the same\n * reason: the mistake should cost that property, not the batch it happens to be in. Truncating a\n * key is not an option — two long keys would silently become one field.\n *\n * The key schema below is deliberately permissive so that this transform is reached at all; the\n * trimming it used to do happens here instead. `MAX_PROPERTIES` keeps the first N in insertion\n * order.\n */\nfunction takeProperties<T>(data: Record<string, T>): Record<string, T> {\n const result: Record<string, T> = {};\n let count = 0;\n for (const [rawKey, value] of Object.entries(data)) {\n if (count >= MAX_PROPERTIES) break;\n const key = rawKey.trim();\n if (!key || key.length > MAX_KEY_LENGTH) continue;\n result[key] = value;\n count++;\n }\n return result;\n}\n\n/**\n * Capped at GA4's own item-list limit, and truncated rather than rejected like every other\n * property limit here: an unbounded array is the one field a caller could still blow a batch\n * up with after the value and key limits.\n */\nconst MAX_ITEMS = 200;\n\nconst items = pipe(\n array(\n pipe(\n record(string(), union([propertyText, number(), boolean(), _null()])),\n transform(takeProperties)\n )\n ),\n transform((list) => list.slice(0, MAX_ITEMS))\n);\n\nexport const ALL_PLATFORMS = [\n 'ios',\n 'android',\n 'web',\n 'macos',\n 'windows',\n 'linux',\n 'unknown',\n] as const satisfies Platform[];\n\nexport const ALL_ENVIRONMENTS = ['development', 'production'] as const satisfies Environment[];\n\nexport const tagsSchema = object({\n os: optional(string()),\n os_name: optional(string()),\n os_version: optional(string()),\n browser: optional(string()),\n browser_name: optional(string()),\n browser_version: optional(string()),\n device: optional(string()),\n device_id: optional(string().check(trim(), minLength(1), maxLength(36))),\n device_type: optional(string()),\n device_vendor: optional(string()),\n device_pixel_ratio: optional(number()),\n screen_width: optional(number()),\n screen_height: optional(number()),\n screen_resolution: optional(\n pipe(\n string().check(regex(/^\\d+x\\d+$/)),\n transform((v) => v as `${number}x${number}`)\n )\n ),\n webdriver: optional(boolean()),\n release: optional(string()),\n language: optional(string()),\n time_zone: optional(string()),\n page_location: optional(string()),\n page_referrer: optional(string()),\n page_title: optional(string()),\n page_load_id: optional(string()),\n /**\n * @deprecated Renamed to `page_location` in 7.0.0. Accepted so that events from clients\n * still on an older SDK are not stripped of their page URL at this boundary — a browser\n * bundle stays cached long after a backend deploys. Remove once those clients are gone;\n * `pageLocation` in `server/page-location.ts` is the only reader.\n */\n source_url: optional(string()),\n // app info\n advertising_id: optional(string()),\n install_referrer: optional(string()),\n // Meta Ads\n fbc: optional(string()),\n fbp: optional(string()),\n fbclid: optional(string()),\n ad_id: optional(string()),\n ad_name: optional(string()),\n adset_id: optional(string()),\n adset_name: optional(string()),\n campaign_id: optional(string()),\n campaign_name: optional(string()),\n placement: optional(string()),\n // Google Ads\n gclid: optional(string()),\n gclsrc: optional(string()),\n gad_source: optional(string()),\n gad_campaignid: optional(string()),\n // Reddit ads\n rdt_cid: optional(string()),\n rdt_uuid: optional(string()),\n // click ids\n dclid: optional(string()),\n ko_click_id: optional(string()),\n li_fat_id: optional(string()),\n msclkid: optional(string()),\n ScCid: optional(string()),\n ttclid: optional(string()),\n twclid: optional(string()),\n wbraid: optional(string()),\n gbraid: optional(string()),\n yclid: optional(string()),\n oppref: optional(string()),\n epik: optional(string()),\n // utm params\n utm_source: optional(string()),\n utm_medium: optional(string()),\n utm_campaign: optional(string()),\n utm_term: optional(string()),\n utm_content: optional(string()),\n utm_id: optional(string()),\n utm_source_platform: optional(string()),\n utm_creative_format: optional(string()),\n utm_marketing_tactic: optional(string()),\n});\n\nexport const propertiesSchema = optional(\n pipe(\n record(string(), union([propertyText, number(), boolean(), _null(), items])),\n transform(takeProperties)\n )\n);\n\n/** Visitor properties differ from event properties only in taking no nested item lists. */\nconst visitorPropertiesSchema = optional(\n pipe(\n record(string(), union([propertyText, number(), boolean(), _null()])),\n transform(takeProperties)\n )\n);\n\n/**\n * How far an event's time may be from the server's before the client clock it was stamped with is\n * taken as wrong. A batch legitimately arrives late — a tab frozen in the background, a\n * session_start held back after a failed batch — by hours, not days; a phone set to another year\n * writes its sessions into that year.\n */\nconst MAX_CLOCK_SKEW = 24 * 60 * 60 * 1000;\n\n/**\n * Puts the events stamped by a wrong client clock onto the server's, where they are parsed. Only\n * the events outside `MAX_CLOCK_SKEW` move, so one bad event cannot drag the rest of its batch\n * along: they move together by their own latest one — the wrong clock at sending — keeping their\n * order and spacing, and one still out after that (a batch mixing two wrong clocks) is on no clock\n * at all and takes the server's time. Corrected rather than rejected, for the same reason values\n * are truncated: a wrong clock should cost the event its time, not the batch its events.\n */\nfunction alignClock<T extends { timestamp: string }>(events: T[], now = Date.now()): T[] {\n const within = (time: number) => Math.abs(now - time) <= MAX_CLOCK_SKEW;\n const times = events.map((event) => Date.parse(event.timestamp));\n const wrong = times.filter((time) => !within(time));\n if (wrong.length === 0) return events;\n const offset = now - Math.max(...wrong);\n return events.map((event, i) => {\n if (within(times[i])) return event;\n const shifted = times[i] + offset;\n return { ...event, timestamp: new Date(within(shifted) ? shifted : now).toISOString() };\n });\n}\n\nexport const createTrackEventSchema = pipe(\n array(\n object({\n name: string().check(trim(), minLength(1), maxLength(64)),\n visitor_id: uuid(),\n session_id: uuid(),\n platform: _enum(ALL_PLATFORMS),\n environment: _enum(ALL_ENVIRONMENTS),\n timestamp: iso.datetime(),\n tags: tagsSchema,\n properties: propertiesSchema,\n })\n ).check(minLength(1), maxLength(100)),\n transform((events) => alignClock(events))\n);\n\nexport const createVisitorSchema = object({\n device_id: string().check(trim(), minLength(1), maxLength(36)),\n platform: _enum(ALL_PLATFORMS),\n environment: _enum(ALL_ENVIRONMENTS),\n tags: tagsSchema,\n properties: visitorPropertiesSchema,\n});\n\nconst emailValue = pipe(string().check(trim(), toLowerCase(), maxLength(320)), email());\n\n/** E.164: a plus sign (+) prefix, country code, then digits only, no dashes/parens/spaces. */\nconst phoneValue = pipe(string().check(trim()), e164());\n\nconst addressValue = object({\n first_name: optional(string().check(trim(), maxLength(128))),\n last_name: optional(string().check(trim(), maxLength(128))),\n street: optional(string().check(trim(), maxLength(256))),\n city: optional(string().check(trim(), maxLength(128))),\n /** User province, state, or region. Example: `Hampshire` */\n region: optional(string().check(trim(), maxLength(128))),\n postal_code: optional(string().check(trim(), maxLength(32))),\n /** 2-letter country code, per the ISO 3166-1 alpha-2 standard. Example: `UK` */\n country: optional(string().check(trim(), toUpperCase(), regex(/^[A-Z]{2}$/))),\n});\n\n/**\n * User-provided data (UPD) used for enhanced conversions, Customer Match, and demographics.\n * Values are sent unhashed; Google normalizes and hashes them before they reach its servers.\n *\n * Multiple values may be sent to increase the match rate: up to 3 emails, 3 phone numbers, and\n * 2 addresses.\n *\n * @see https://support.google.com/analytics/answer/14078702\n * @see https://support.google.com/google-ads/answer/13258081\n */\nexport const userProvidedDataSchema = object({\n email: optional(union([emailValue, array(emailValue).check(minLength(1), maxLength(3))])),\n phone_number: optional(union([phoneValue, array(phoneValue).check(minLength(1), maxLength(3))])),\n address: optional(union([addressValue, array(addressValue).check(minLength(1), maxLength(2))])),\n});\n\nexport const updateVisitorSchema = object({\n user_id: optional(uuid()),\n user_data: optional(userProvidedDataSchema),\n tags: tagsSchema,\n properties: visitorPropertiesSchema,\n});\n\nexport const createFeedbackSchema = object({\n name: string().check(minLength(1), maxLength(256)),\n email: email().check(maxLength(320)),\n message: string().check(minLength(1), maxLength(65536)),\n});\n\nconst noEmptyString = pipe(\n string().check(maxLength(256)),\n transform((v) => (v ? v : undefined))\n);\n\n/**\n * The schema for creating a link.\n * @see https://support.google.com/analytics/answer/10917952\n * */\nexport const createLinkSchema = object({\n /** The URL that the user is redirected to. */\n url: url().check(minLength(1), maxLength(1024)), // required\n\n /**\n * Campaign ID. Used to identify a specific campaign or promotion. This is a required key for GA4\n * data import. Use the same IDs that you use when uploading campaign cost data.\n */\n utm_id: optional(noEmptyString),\n\n /** Referrer, for example: google, newsletter4, billboard */\n utm_source: string().check(minLength(1), maxLength(256)), // required\n\n /** Marketing medium, for example: cpc, banner, email */\n utm_medium: string().check(minLength(1), maxLength(256)), // required\n\n /** Product, slogan, promo code, for example, spring_sale */\n utm_campaign: string().check(minLength(1), maxLength(256)), // required\n\n /** Paid keyword */\n utm_term: optional(noEmptyString),\n\n /**\n * Use to differentiate creatives. For example, if you have two call-to-action links within the\n * same email message, you can use utm_content and set different values for each so you can tell\n * which version is more effective.\n */\n utm_content: optional(noEmptyString),\n\n /**\n * The platform responsible for directing traffic to a given Analytics property (such as a buying\n * platform that sets budgets and targeting criteria or a platform that manages organic traffic\n * data). For example, Search Ads 360 or Display & Video 360.\n */\n utm_source_platform: optional(noEmptyString),\n\n /**\n * Type of creative, for example, display, native, video, search, utm_creative_format is not\n * currently reported in Google Analytics 4 properties.\n */\n utm_creative_format: optional(noEmptyString),\n\n /**\n * Targeting criteria applied to a campaign, for example, remarketing, prospecting,\n * utm_marketing_tactic is not currently reported in Google Analytics 4 properties.\n * */\n utm_marketing_tactic: optional(noEmptyString),\n});\n\nexport type CreateTrackEventDTO = z.output<typeof createTrackEventSchema>;\nexport type CreateFeedbackDTO = z.output<typeof createFeedbackSchema>;\nexport type CreateLinkDTO = z.output<typeof createLinkSchema>;\nexport type CreateVisitorDTO = z.output<typeof createVisitorSchema>;\nexport type UserProvidedDataDTO = z.output<typeof userProvidedDataSchema>;\nexport type UpdateVisitorDTO = z.output<typeof updateVisitorSchema>;\n"],"mappings":"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"}
@@ -48,12 +48,14 @@ export declare const tagsSchema: z.ZodMiniObject<{
48
48
  ko_click_id: z.ZodMiniOptional<z.ZodMiniString<string>>;
49
49
  li_fat_id: z.ZodMiniOptional<z.ZodMiniString<string>>;
50
50
  msclkid: z.ZodMiniOptional<z.ZodMiniString<string>>;
51
- sccid: z.ZodMiniOptional<z.ZodMiniString<string>>;
51
+ ScCid: z.ZodMiniOptional<z.ZodMiniString<string>>;
52
52
  ttclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
53
53
  twclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
54
54
  wbraid: z.ZodMiniOptional<z.ZodMiniString<string>>;
55
55
  gbraid: z.ZodMiniOptional<z.ZodMiniString<string>>;
56
56
  yclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
57
+ oppref: z.ZodMiniOptional<z.ZodMiniString<string>>;
58
+ epik: z.ZodMiniOptional<z.ZodMiniString<string>>;
57
59
  utm_source: z.ZodMiniOptional<z.ZodMiniString<string>>;
58
60
  utm_medium: z.ZodMiniOptional<z.ZodMiniString<string>>;
59
61
  utm_campaign: z.ZodMiniOptional<z.ZodMiniString<string>>;
@@ -129,12 +131,14 @@ export declare const createTrackEventSchema: z.ZodMiniPipe<z.ZodMiniArray<z.ZodM
129
131
  ko_click_id: z.ZodMiniOptional<z.ZodMiniString<string>>;
130
132
  li_fat_id: z.ZodMiniOptional<z.ZodMiniString<string>>;
131
133
  msclkid: z.ZodMiniOptional<z.ZodMiniString<string>>;
132
- sccid: z.ZodMiniOptional<z.ZodMiniString<string>>;
134
+ ScCid: z.ZodMiniOptional<z.ZodMiniString<string>>;
133
135
  ttclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
134
136
  twclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
135
137
  wbraid: z.ZodMiniOptional<z.ZodMiniString<string>>;
136
138
  gbraid: z.ZodMiniOptional<z.ZodMiniString<string>>;
137
139
  yclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
140
+ oppref: z.ZodMiniOptional<z.ZodMiniString<string>>;
141
+ epik: z.ZodMiniOptional<z.ZodMiniString<string>>;
138
142
  utm_source: z.ZodMiniOptional<z.ZodMiniString<string>>;
139
143
  utm_medium: z.ZodMiniOptional<z.ZodMiniString<string>>;
140
144
  utm_campaign: z.ZodMiniOptional<z.ZodMiniString<string>>;
@@ -199,12 +203,14 @@ export declare const createTrackEventSchema: z.ZodMiniPipe<z.ZodMiniArray<z.ZodM
199
203
  ko_click_id?: string | undefined;
200
204
  li_fat_id?: string | undefined;
201
205
  msclkid?: string | undefined;
202
- sccid?: string | undefined;
206
+ ScCid?: string | undefined;
203
207
  ttclid?: string | undefined;
204
208
  twclid?: string | undefined;
205
209
  wbraid?: string | undefined;
206
210
  gbraid?: string | undefined;
207
211
  yclid?: string | undefined;
212
+ oppref?: string | undefined;
213
+ epik?: string | undefined;
208
214
  utm_source?: string | undefined;
209
215
  utm_medium?: string | undefined;
210
216
  utm_campaign?: string | undefined;
@@ -269,12 +275,14 @@ export declare const createTrackEventSchema: z.ZodMiniPipe<z.ZodMiniArray<z.ZodM
269
275
  ko_click_id?: string | undefined;
270
276
  li_fat_id?: string | undefined;
271
277
  msclkid?: string | undefined;
272
- sccid?: string | undefined;
278
+ ScCid?: string | undefined;
273
279
  ttclid?: string | undefined;
274
280
  twclid?: string | undefined;
275
281
  wbraid?: string | undefined;
276
282
  gbraid?: string | undefined;
277
283
  yclid?: string | undefined;
284
+ oppref?: string | undefined;
285
+ epik?: string | undefined;
278
286
  utm_source?: string | undefined;
279
287
  utm_medium?: string | undefined;
280
288
  utm_campaign?: string | undefined;
@@ -348,12 +356,14 @@ export declare const createVisitorSchema: z.ZodMiniObject<{
348
356
  ko_click_id: z.ZodMiniOptional<z.ZodMiniString<string>>;
349
357
  li_fat_id: z.ZodMiniOptional<z.ZodMiniString<string>>;
350
358
  msclkid: z.ZodMiniOptional<z.ZodMiniString<string>>;
351
- sccid: z.ZodMiniOptional<z.ZodMiniString<string>>;
359
+ ScCid: z.ZodMiniOptional<z.ZodMiniString<string>>;
352
360
  ttclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
353
361
  twclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
354
362
  wbraid: z.ZodMiniOptional<z.ZodMiniString<string>>;
355
363
  gbraid: z.ZodMiniOptional<z.ZodMiniString<string>>;
356
364
  yclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
365
+ oppref: z.ZodMiniOptional<z.ZodMiniString<string>>;
366
+ epik: z.ZodMiniOptional<z.ZodMiniString<string>>;
357
367
  utm_source: z.ZodMiniOptional<z.ZodMiniString<string>>;
358
368
  utm_medium: z.ZodMiniOptional<z.ZodMiniString<string>>;
359
369
  utm_campaign: z.ZodMiniOptional<z.ZodMiniString<string>>;
@@ -466,12 +476,14 @@ export declare const updateVisitorSchema: z.ZodMiniObject<{
466
476
  ko_click_id: z.ZodMiniOptional<z.ZodMiniString<string>>;
467
477
  li_fat_id: z.ZodMiniOptional<z.ZodMiniString<string>>;
468
478
  msclkid: z.ZodMiniOptional<z.ZodMiniString<string>>;
469
- sccid: z.ZodMiniOptional<z.ZodMiniString<string>>;
479
+ ScCid: z.ZodMiniOptional<z.ZodMiniString<string>>;
470
480
  ttclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
471
481
  twclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
472
482
  wbraid: z.ZodMiniOptional<z.ZodMiniString<string>>;
473
483
  gbraid: z.ZodMiniOptional<z.ZodMiniString<string>>;
474
484
  yclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
485
+ oppref: z.ZodMiniOptional<z.ZodMiniString<string>>;
486
+ epik: z.ZodMiniOptional<z.ZodMiniString<string>>;
475
487
  utm_source: z.ZodMiniOptional<z.ZodMiniString<string>>;
476
488
  utm_medium: z.ZodMiniOptional<z.ZodMiniString<string>>;
477
489
  utm_campaign: z.ZodMiniOptional<z.ZodMiniString<string>>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/schema/index.ts"],"mappings":";;qBAmFa;qBAUA;qBAEA,YAAU,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8ErB,EAAA,KAAA;qBAEW,kBAAgB,EAAA,gBAAA,EAAA,YAAA,EAAA,cAAA,EAAA,uBAAA,EAAA,uBAAA,EAAA,YAAA,EAAA,uBAAA,EAAA,mCAAA,EAAA,uBAAA,EAAA,yBAAA,EAAA,aAAA,EAAA,YAAA,EAAA,aAAA,EAAA,YAAA,EAAA,cAAA,EAAA,uBAAA,EAAA,uBAAA,EAAA,YAAA,EAAA,uBAAA,EAAA,mCAAA,EAAA,uBAAA,EAAA,yBAAA,EAAA,gBAAA,EAAA,iBAAA,kDAAA,qDAAA,EAAA,iBAAA,oDAAA,yDAAA,EAAA,iBAAA,2CAAA,4DAAA,2CAAA;qBA4ChB,wBAAsB,EAAA,YAAA,EAAA,aAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAgBtB,qBAAmB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAM9B,EAAA,KAAA;;;;;;;;;;;qBA6BW,wBAAsB,EAAA;;;;;;;;;;;;;;;;;;;;GAIjC,EAAA,KAAA;qBAEW,qBAAmB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAK9B,EAAA,KAAA;qBAEW,sBAAoB,EAAA;;;;GAI/B,EAAA,KAAA;;;;;qBAWW,kBAAgB,EAAA;;;;;;;;;;;GA+C3B,EAAA,KAAA;YAEU,sBAAsB,EAAE,cAAc;YACtC,oBAAoB,EAAE,cAAc;YACpC,gBAAgB,EAAE,cAAc;YAChC,mBAAmB,EAAE,cAAc;YACnC,sBAAsB,EAAE,cAAc;YACtC,mBAAmB,EAAE,cAAc"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/schema/index.ts"],"mappings":";;qBAmFa;qBAUA;qBAEA,YAAU,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFrB,EAAA,KAAA;qBAEW,kBAAgB,EAAA,gBAAA,EAAA,YAAA,EAAA,cAAA,EAAA,uBAAA,EAAA,uBAAA,EAAA,YAAA,EAAA,uBAAA,EAAA,mCAAA,EAAA,uBAAA,EAAA,yBAAA,EAAA,aAAA,EAAA,YAAA,EAAA,aAAA,EAAA,YAAA,EAAA,cAAA,EAAA,uBAAA,EAAA,uBAAA,EAAA,YAAA,EAAA,uBAAA,EAAA,mCAAA,EAAA,uBAAA,EAAA,yBAAA,EAAA,gBAAA,EAAA,iBAAA,kDAAA,qDAAA,EAAA,iBAAA,oDAAA,yDAAA,EAAA,iBAAA,2CAAA,4DAAA,2CAAA;qBA4ChB,wBAAsB,EAAA,YAAA,EAAA,aAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAgBtB,qBAAmB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAM9B,EAAA,KAAA;;;;;;;;;;;qBA6BW,wBAAsB,EAAA;;;;;;;;;;;;;;;;;;;;GAIjC,EAAA,KAAA;qBAEW,qBAAmB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAK9B,EAAA,KAAA;qBAEW,sBAAoB,EAAA;;;;GAI/B,EAAA,KAAA;;;;;qBAWW,kBAAgB,EAAA;;;;;;;;;;;GA+C3B,EAAA,KAAA;YAEU,sBAAsB,EAAE,cAAc;YACtC,oBAAoB,EAAE,cAAc;YACpC,gBAAgB,EAAE,cAAc;YAChC,mBAAmB,EAAE,cAAc;YACnC,sBAAsB,EAAE,cAAc;YACtC,mBAAmB,EAAE,cAAc"}
@@ -48,12 +48,14 @@ export declare const tagsSchema: z.ZodMiniObject<{
48
48
  ko_click_id: z.ZodMiniOptional<z.ZodMiniString<string>>;
49
49
  li_fat_id: z.ZodMiniOptional<z.ZodMiniString<string>>;
50
50
  msclkid: z.ZodMiniOptional<z.ZodMiniString<string>>;
51
- sccid: z.ZodMiniOptional<z.ZodMiniString<string>>;
51
+ ScCid: z.ZodMiniOptional<z.ZodMiniString<string>>;
52
52
  ttclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
53
53
  twclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
54
54
  wbraid: z.ZodMiniOptional<z.ZodMiniString<string>>;
55
55
  gbraid: z.ZodMiniOptional<z.ZodMiniString<string>>;
56
56
  yclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
57
+ oppref: z.ZodMiniOptional<z.ZodMiniString<string>>;
58
+ epik: z.ZodMiniOptional<z.ZodMiniString<string>>;
57
59
  utm_source: z.ZodMiniOptional<z.ZodMiniString<string>>;
58
60
  utm_medium: z.ZodMiniOptional<z.ZodMiniString<string>>;
59
61
  utm_campaign: z.ZodMiniOptional<z.ZodMiniString<string>>;
@@ -129,12 +131,14 @@ export declare const createTrackEventSchema: z.ZodMiniPipe<z.ZodMiniArray<z.ZodM
129
131
  ko_click_id: z.ZodMiniOptional<z.ZodMiniString<string>>;
130
132
  li_fat_id: z.ZodMiniOptional<z.ZodMiniString<string>>;
131
133
  msclkid: z.ZodMiniOptional<z.ZodMiniString<string>>;
132
- sccid: z.ZodMiniOptional<z.ZodMiniString<string>>;
134
+ ScCid: z.ZodMiniOptional<z.ZodMiniString<string>>;
133
135
  ttclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
134
136
  twclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
135
137
  wbraid: z.ZodMiniOptional<z.ZodMiniString<string>>;
136
138
  gbraid: z.ZodMiniOptional<z.ZodMiniString<string>>;
137
139
  yclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
140
+ oppref: z.ZodMiniOptional<z.ZodMiniString<string>>;
141
+ epik: z.ZodMiniOptional<z.ZodMiniString<string>>;
138
142
  utm_source: z.ZodMiniOptional<z.ZodMiniString<string>>;
139
143
  utm_medium: z.ZodMiniOptional<z.ZodMiniString<string>>;
140
144
  utm_campaign: z.ZodMiniOptional<z.ZodMiniString<string>>;
@@ -199,12 +203,14 @@ export declare const createTrackEventSchema: z.ZodMiniPipe<z.ZodMiniArray<z.ZodM
199
203
  ko_click_id?: string | undefined;
200
204
  li_fat_id?: string | undefined;
201
205
  msclkid?: string | undefined;
202
- sccid?: string | undefined;
206
+ ScCid?: string | undefined;
203
207
  ttclid?: string | undefined;
204
208
  twclid?: string | undefined;
205
209
  wbraid?: string | undefined;
206
210
  gbraid?: string | undefined;
207
211
  yclid?: string | undefined;
212
+ oppref?: string | undefined;
213
+ epik?: string | undefined;
208
214
  utm_source?: string | undefined;
209
215
  utm_medium?: string | undefined;
210
216
  utm_campaign?: string | undefined;
@@ -269,12 +275,14 @@ export declare const createTrackEventSchema: z.ZodMiniPipe<z.ZodMiniArray<z.ZodM
269
275
  ko_click_id?: string | undefined;
270
276
  li_fat_id?: string | undefined;
271
277
  msclkid?: string | undefined;
272
- sccid?: string | undefined;
278
+ ScCid?: string | undefined;
273
279
  ttclid?: string | undefined;
274
280
  twclid?: string | undefined;
275
281
  wbraid?: string | undefined;
276
282
  gbraid?: string | undefined;
277
283
  yclid?: string | undefined;
284
+ oppref?: string | undefined;
285
+ epik?: string | undefined;
278
286
  utm_source?: string | undefined;
279
287
  utm_medium?: string | undefined;
280
288
  utm_campaign?: string | undefined;
@@ -348,12 +356,14 @@ export declare const createVisitorSchema: z.ZodMiniObject<{
348
356
  ko_click_id: z.ZodMiniOptional<z.ZodMiniString<string>>;
349
357
  li_fat_id: z.ZodMiniOptional<z.ZodMiniString<string>>;
350
358
  msclkid: z.ZodMiniOptional<z.ZodMiniString<string>>;
351
- sccid: z.ZodMiniOptional<z.ZodMiniString<string>>;
359
+ ScCid: z.ZodMiniOptional<z.ZodMiniString<string>>;
352
360
  ttclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
353
361
  twclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
354
362
  wbraid: z.ZodMiniOptional<z.ZodMiniString<string>>;
355
363
  gbraid: z.ZodMiniOptional<z.ZodMiniString<string>>;
356
364
  yclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
365
+ oppref: z.ZodMiniOptional<z.ZodMiniString<string>>;
366
+ epik: z.ZodMiniOptional<z.ZodMiniString<string>>;
357
367
  utm_source: z.ZodMiniOptional<z.ZodMiniString<string>>;
358
368
  utm_medium: z.ZodMiniOptional<z.ZodMiniString<string>>;
359
369
  utm_campaign: z.ZodMiniOptional<z.ZodMiniString<string>>;
@@ -466,12 +476,14 @@ export declare const updateVisitorSchema: z.ZodMiniObject<{
466
476
  ko_click_id: z.ZodMiniOptional<z.ZodMiniString<string>>;
467
477
  li_fat_id: z.ZodMiniOptional<z.ZodMiniString<string>>;
468
478
  msclkid: z.ZodMiniOptional<z.ZodMiniString<string>>;
469
- sccid: z.ZodMiniOptional<z.ZodMiniString<string>>;
479
+ ScCid: z.ZodMiniOptional<z.ZodMiniString<string>>;
470
480
  ttclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
471
481
  twclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
472
482
  wbraid: z.ZodMiniOptional<z.ZodMiniString<string>>;
473
483
  gbraid: z.ZodMiniOptional<z.ZodMiniString<string>>;
474
484
  yclid: z.ZodMiniOptional<z.ZodMiniString<string>>;
485
+ oppref: z.ZodMiniOptional<z.ZodMiniString<string>>;
486
+ epik: z.ZodMiniOptional<z.ZodMiniString<string>>;
475
487
  utm_source: z.ZodMiniOptional<z.ZodMiniString<string>>;
476
488
  utm_medium: z.ZodMiniOptional<z.ZodMiniString<string>>;
477
489
  utm_campaign: z.ZodMiniOptional<z.ZodMiniString<string>>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/schema/index.ts"],"mappings":";;qBAmFa;qBAUA;qBAEA,YAAU,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8ErB,EAAA,KAAA;qBAEW,kBAAgB,EAAA,gBAAA,EAAA,YAAA,EAAA,cAAA,EAAA,uBAAA,EAAA,uBAAA,EAAA,YAAA,EAAA,uBAAA,EAAA,mCAAA,EAAA,uBAAA,EAAA,yBAAA,EAAA,aAAA,EAAA,YAAA,EAAA,aAAA,EAAA,YAAA,EAAA,cAAA,EAAA,uBAAA,EAAA,uBAAA,EAAA,YAAA,EAAA,uBAAA,EAAA,mCAAA,EAAA,uBAAA,EAAA,yBAAA,EAAA,gBAAA,EAAA,iBAAA,kDAAA,qDAAA,EAAA,iBAAA,oDAAA,yDAAA,EAAA,iBAAA,2CAAA,4DAAA,2CAAA;qBA4ChB,wBAAsB,EAAA,YAAA,EAAA,aAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAgBtB,qBAAmB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAM9B,EAAA,KAAA;;;;;;;;;;;qBA6BW,wBAAsB,EAAA;;;;;;;;;;;;;;;;;;;;GAIjC,EAAA,KAAA;qBAEW,qBAAmB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAK9B,EAAA,KAAA;qBAEW,sBAAoB,EAAA;;;;GAI/B,EAAA,KAAA;;;;;qBAWW,kBAAgB,EAAA;;;;;;;;;;;GA+C3B,EAAA,KAAA;YAEU,sBAAsB,EAAE,cAAc;YACtC,oBAAoB,EAAE,cAAc;YACpC,gBAAgB,EAAE,cAAc;YAChC,mBAAmB,EAAE,cAAc;YACnC,sBAAsB,EAAE,cAAc;YACtC,mBAAmB,EAAE,cAAc"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/schema/index.ts"],"mappings":";;qBAmFa;qBAUA;qBAEA,YAAU,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFrB,EAAA,KAAA;qBAEW,kBAAgB,EAAA,gBAAA,EAAA,YAAA,EAAA,cAAA,EAAA,uBAAA,EAAA,uBAAA,EAAA,YAAA,EAAA,uBAAA,EAAA,mCAAA,EAAA,uBAAA,EAAA,yBAAA,EAAA,aAAA,EAAA,YAAA,EAAA,aAAA,EAAA,YAAA,EAAA,cAAA,EAAA,uBAAA,EAAA,uBAAA,EAAA,YAAA,EAAA,uBAAA,EAAA,mCAAA,EAAA,uBAAA,EAAA,yBAAA,EAAA,gBAAA,EAAA,iBAAA,kDAAA,qDAAA,EAAA,iBAAA,oDAAA,yDAAA,EAAA,iBAAA,2CAAA,4DAAA,2CAAA;qBA4ChB,wBAAsB,EAAA,YAAA,EAAA,aAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAgBtB,qBAAmB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAM9B,EAAA,KAAA;;;;;;;;;;;qBA6BW,wBAAsB,EAAA;;;;;;;;;;;;;;;;;;;;GAIjC,EAAA,KAAA;qBAEW,qBAAmB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAK9B,EAAA,KAAA;qBAEW,sBAAoB,EAAA;;;;GAI/B,EAAA,KAAA;;;;;qBAWW,kBAAgB,EAAA;;;;;;;;;;;GA+C3B,EAAA,KAAA;YAEU,sBAAsB,EAAE,cAAc;YACtC,oBAAoB,EAAE,cAAc;YACpC,gBAAgB,EAAE,cAAc;YAChC,mBAAmB,EAAE,cAAc;YACnC,sBAAsB,EAAE,cAAc;YACtC,mBAAmB,EAAE,cAAc"}
@@ -106,12 +106,14 @@ const tagsSchema = object({
106
106
  ko_click_id: optional(string()),
107
107
  li_fat_id: optional(string()),
108
108
  msclkid: optional(string()),
109
- sccid: optional(string()),
109
+ ScCid: optional(string()),
110
110
  ttclid: optional(string()),
111
111
  twclid: optional(string()),
112
112
  wbraid: optional(string()),
113
113
  gbraid: optional(string()),
114
114
  yclid: optional(string()),
115
+ oppref: optional(string()),
116
+ epik: optional(string()),
115
117
  utm_source: optional(string()),
116
118
  utm_medium: optional(string()),
117
119
  utm_campaign: optional(string()),