lytx 0.3.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.
- package/.env.example +37 -0
- package/README.md +486 -0
- package/alchemy.run.ts +155 -0
- package/cli/bootstrap-admin.ts +284 -0
- package/cli/deploy-staging.ts +692 -0
- package/cli/import-events.ts +628 -0
- package/cli/import-sites.ts +518 -0
- package/cli/index.ts +609 -0
- package/cli/init-db.ts +269 -0
- package/cli/migrate-to-durable-objects.ts +564 -0
- package/cli/migration-worker.ts +300 -0
- package/cli/performance-test.ts +588 -0
- package/cli/pg/client.ts +4 -0
- package/cli/pg/new-site.ts +153 -0
- package/cli/rollback-durable-objects.ts +622 -0
- package/cli/seed-data.ts +459 -0
- package/cli/setup.js +18 -0
- package/cli/setup.ts +463 -0
- package/cli/validate-migration.ts +200 -0
- package/cli/wrangler-migration.jsonc +28 -0
- package/db/adapter.ts +166 -0
- package/db/analytics_engine/client.ts +0 -0
- package/db/analytics_engine/sites.ts +0 -0
- package/db/client.ts +16 -0
- package/db/d1/client.ts +8 -0
- package/db/d1/drizzle.config.ts +35 -0
- package/db/d1/migrations/0000_true_maelstrom.sql +165 -0
- package/db/d1/migrations/0001_wonderful_bloodaxe.sql +12 -0
- package/db/d1/migrations/0002_late_frightful_four.sql +1 -0
- package/db/d1/migrations/0003_cuddly_obadiah_stane.sql +16 -0
- package/db/d1/migrations/0004_mute_stardust.sql +1 -0
- package/db/d1/migrations/0005_awesome_silvermane.sql +3 -0
- package/db/d1/migrations/0006_volatile_shriek.sql +2 -0
- package/db/d1/migrations/0007_superb_lila_cheney.sql +1 -0
- package/db/d1/migrations/0008_bitter_longshot.sql +17 -0
- package/db/d1/migrations/0009_wonderful_madame_masque.sql +28 -0
- package/db/d1/migrations/meta/0000_snapshot.json +1112 -0
- package/db/d1/migrations/meta/0001_snapshot.json +1187 -0
- package/db/d1/migrations/meta/0002_snapshot.json +1194 -0
- package/db/d1/migrations/meta/0003_snapshot.json +1296 -0
- package/db/d1/migrations/meta/0004_snapshot.json +1303 -0
- package/db/d1/migrations/meta/0005_snapshot.json +1325 -0
- package/db/d1/migrations/meta/0006_snapshot.json +1339 -0
- package/db/d1/migrations/meta/0007_snapshot.json +1347 -0
- package/db/d1/migrations/meta/0008_snapshot.json +1464 -0
- package/db/d1/migrations/meta/0009_snapshot.json +1648 -0
- package/db/d1/migrations/meta/_journal.json +76 -0
- package/db/d1/schema.ts +407 -0
- package/db/d1/sites.ts +374 -0
- package/db/d1/teamAiUsage.ts +101 -0
- package/db/d1/teams.ts +127 -0
- package/db/durable/drizzle.config.ts +8 -0
- package/db/durable/durableObjectClient.ts +480 -0
- package/db/durable/events.ts +100 -0
- package/db/durable/migrations/0000_fair_bucky.sql +38 -0
- package/db/durable/migrations/meta/0000_snapshot.json +278 -0
- package/db/durable/migrations/meta/_journal.json +13 -0
- package/db/durable/migrations/migrations.js +10 -0
- package/db/durable/schema.ts +5 -0
- package/db/durable/siteDurableObject.ts +1352 -0
- package/db/durable/types.ts +53 -0
- package/db/postgres/client.ts +13 -0
- package/db/postgres/drizzle.config.ts +12 -0
- package/db/postgres/migrations/0000_brainy_sprite.sql +116 -0
- package/db/postgres/migrations/meta/0000_snapshot.json +681 -0
- package/db/postgres/migrations/meta/_journal.json +13 -0
- package/db/postgres/schema.ts +145 -0
- package/db/postgres/sites.ts +118 -0
- package/db/tranformReports.ts +595 -0
- package/db/types.ts +55 -0
- package/endpoints/api_worker.tsx +1854 -0
- package/endpoints/site_do_worker.ts +11 -0
- package/index.d.ts +63 -0
- package/index.ts +83 -0
- package/lib/auth.ts +279 -0
- package/lib/geojson/world_countries.json +45307 -0
- package/lib/random_name.ts +41 -0
- package/lib/sendMail.ts +252 -0
- package/package.json +142 -0
- package/public/favicon.ico +0 -0
- package/public/images/android-chrome-192x192.png +0 -0
- package/public/images/android-chrome-512x512.png +0 -0
- package/public/images/apple-touch-icon.png +0 -0
- package/public/images/favicon-16x16.png +0 -0
- package/public/images/favicon-32x32.png +0 -0
- package/public/images/lytx_dark_dashboard.png +0 -0
- package/public/images/lytx_light_dashboard.png +0 -0
- package/public/images/safari-pinned-tab.svg +4 -0
- package/public/logo.png +0 -0
- package/public/site.webmanifest +26 -0
- package/public/sw.js +107 -0
- package/src/Document.tsx +86 -0
- package/src/api/ai_api.ts +1156 -0
- package/src/api/authMiddleware.ts +45 -0
- package/src/api/auth_api.ts +465 -0
- package/src/api/event_labels_api.ts +193 -0
- package/src/api/events_api.ts +210 -0
- package/src/api/queueWorker.ts +303 -0
- package/src/api/reports_api.ts +278 -0
- package/src/api/seed_api.ts +288 -0
- package/src/api/sites_api.ts +904 -0
- package/src/api/tag_api.ts +458 -0
- package/src/api/tag_api_v2.ts +289 -0
- package/src/api/team_api.ts +456 -0
- package/src/app/Dashboard.tsx +1339 -0
- package/src/app/Events.tsx +974 -0
- package/src/app/Explore.tsx +312 -0
- package/src/app/Layout.tsx +58 -0
- package/src/app/Settings.tsx +1302 -0
- package/src/app/components/DashboardCard.tsx +118 -0
- package/src/app/components/EditableCell.tsx +123 -0
- package/src/app/components/EventForm.tsx +93 -0
- package/src/app/components/MarketingFooter.tsx +49 -0
- package/src/app/components/MarketingNav.tsx +150 -0
- package/src/app/components/Nav.tsx +755 -0
- package/src/app/components/NewSiteSetup.tsx +298 -0
- package/src/app/components/SQLEditor.tsx +740 -0
- package/src/app/components/SiteSelector.tsx +126 -0
- package/src/app/components/SiteTag.tsx +42 -0
- package/src/app/components/SiteTagInstallCard.tsx +241 -0
- package/src/app/components/WorldMapCard.tsx +337 -0
- package/src/app/components/charts/ChartComponents.tsx +1481 -0
- package/src/app/components/charts/EventFunnel.tsx +45 -0
- package/src/app/components/charts/EventSummary.tsx +194 -0
- package/src/app/components/charts/SankeyFlows.tsx +72 -0
- package/src/app/components/marketing/CheckIcon.tsx +16 -0
- package/src/app/components/marketing/MarketingLayout.tsx +23 -0
- package/src/app/components/marketing/SectionHeading.tsx +35 -0
- package/src/app/components/reports/AskAiWorkspace.tsx +371 -0
- package/src/app/components/reports/CreateReportStarter.tsx +74 -0
- package/src/app/components/reports/DashboardRouteFiltersContext.tsx +14 -0
- package/src/app/components/reports/DashboardToolbar.tsx +154 -0
- package/src/app/components/reports/DashboardWorkspaceLayout.tsx +63 -0
- package/src/app/components/reports/DashboardWorkspaceShell.tsx +118 -0
- package/src/app/components/reports/ReportBuilderWorkspace.tsx +76 -0
- package/src/app/components/reports/custom/CustomReportBuilderPage.tsx +1667 -0
- package/src/app/components/reports/custom/ReportWidgetChart.tsx +297 -0
- package/src/app/components/reports/custom/buildWidgetSql.ts +151 -0
- package/src/app/components/reports/custom/chartPalettes.ts +18 -0
- package/src/app/components/reports/custom/types.ts +50 -0
- package/src/app/components/reports/reportBuilderMenuItems.ts +17 -0
- package/src/app/components/reports/useDashboardToolbarControls.tsx +235 -0
- package/src/app/components/ui/AlertBanner.tsx +101 -0
- package/src/app/components/ui/Button.tsx +55 -0
- package/src/app/components/ui/Card.tsx +80 -0
- package/src/app/components/ui/Input.tsx +72 -0
- package/src/app/components/ui/Link.tsx +23 -0
- package/src/app/components/ui/ReportBuilderMenu.tsx +246 -0
- package/src/app/components/ui/ThemeToggle.tsx +54 -0
- package/src/app/constants.ts +6 -0
- package/src/app/headers.ts +33 -0
- package/src/app/providers/AuthProvider.tsx +189 -0
- package/src/app/providers/ClientProviders.tsx +18 -0
- package/src/app/providers/QueryProvider.tsx +23 -0
- package/src/app/providers/ThemeProvider.tsx +88 -0
- package/src/app/utils/chartThemes.ts +146 -0
- package/src/app/utils/keybinds.ts +96 -0
- package/src/app/utils/media.tsx +24 -0
- package/src/client.tsx +114 -0
- package/src/config/createLytxAppConfig.ts +252 -0
- package/src/config/resourceNames.ts +88 -0
- package/src/db/index.ts +67 -0
- package/src/index.css +285 -0
- package/src/lib/featureFlags.ts +69 -0
- package/src/pages/GetStarted.tsx +290 -0
- package/src/pages/Home.tsx +268 -0
- package/src/pages/Login.tsx +283 -0
- package/src/pages/PrivacyPolicy.tsx +120 -0
- package/src/pages/Signup.tsx +267 -0
- package/src/pages/TermsOfService.tsx +126 -0
- package/src/pages/VerifyEmail.tsx +56 -0
- package/src/session/durableObject.ts +7 -0
- package/src/session/siteSchema.ts +86 -0
- package/src/session/types.ts +36 -0
- package/src/templates/README.md +80 -0
- package/src/templates/cleanFunctions.js +44 -0
- package/src/templates/embedFunctions.js +52 -0
- package/src/templates/lytx-shared.ts +662 -0
- package/src/templates/lytxpixel-core.ts +144 -0
- package/src/templates/lytxpixel.ts +267 -0
- package/src/templates/lytxpixelBrowser.js +634 -0
- package/src/templates/lytxpixelBrowser.mjs +634 -0
- package/src/templates/parseData.js +12 -0
- package/src/templates/script.ts +31 -0
- package/src/templates/template.tsx +50 -0
- package/src/templates/test.js +3 -0
- package/src/templates/trackWebEvents.ts +177 -0
- package/src/templates/vendors/clickcease.ts +8 -0
- package/src/templates/vendors/google.ts +174 -0
- package/src/templates/vendors/linkedin.ts +23 -0
- package/src/templates/vendors/meta.ts +56 -0
- package/src/templates/vendors/quantcast.ts +22 -0
- package/src/templates/vendors/simplfi.ts +7 -0
- package/src/types/app-context.ts +16 -0
- package/src/utilities/dashboardParams.ts +188 -0
- package/src/utilities/dashboardQueries.ts +537 -0
- package/src/utilities/dashboardTransforms.ts +167 -0
- package/src/utilities/dataValidation.ts +414 -0
- package/src/utilities/detector.ts +73 -0
- package/src/utilities/encrypt.ts +103 -0
- package/src/utilities/index.ts +13 -0
- package/src/utilities/parser.ts +117 -0
- package/src/utilities/performanceMonitoring.ts +570 -0
- package/src/utilities/route_interuptors.ts +24 -0
- package/src/worker.tsx +675 -0
- package/tsconfig.json +78 -0
- package/types/env.d.ts +16 -0
- package/types/rw.d.ts +7 -0
- package/types/shims.d.ts +53 -0
- package/types/vite.d.ts +19 -0
- package/vite/vite-plugin-pixel-bundle.ts +126 -0
- package/vite.config.ts +53 -0
- package/worker-configuration.d.ts +8401 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { html } from "hono/html";
|
|
2
|
+
|
|
3
|
+
export interface SiteData {
|
|
4
|
+
children?: any;
|
|
5
|
+
head?: { title: string };
|
|
6
|
+
includeHTMX?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export const AppScript = (props: { data: string }) => html`
|
|
9
|
+
<script type="module">
|
|
10
|
+
import {startApp} from "./js/app.js";
|
|
11
|
+
await startApp(${props.data});
|
|
12
|
+
</script>
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
export const Layout = (props: SiteData) => html`<!DOCTYPE html>
|
|
16
|
+
<html>
|
|
17
|
+
<head>
|
|
18
|
+
<meta charset="UTF-8" />
|
|
19
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
20
|
+
<link
|
|
21
|
+
rel="apple-touch-icon"
|
|
22
|
+
sizes="180x180"
|
|
23
|
+
href="https://cdn.lytx.io/static%2Fapple-touch-icon.png"
|
|
24
|
+
/>
|
|
25
|
+
<link
|
|
26
|
+
rel="icon"
|
|
27
|
+
type="image/png"
|
|
28
|
+
sizes="32x32"
|
|
29
|
+
href="https://cdn.lytx.io/static%2Ffavicon-32x32.png"
|
|
30
|
+
/>
|
|
31
|
+
<link
|
|
32
|
+
rel="icon"
|
|
33
|
+
type="image/png"
|
|
34
|
+
sizes="16x16"
|
|
35
|
+
href="https://cdn.lytx.io/static%2Ffavicon-16x16.png"
|
|
36
|
+
/>
|
|
37
|
+
|
|
38
|
+
<link rel="manifest" href="https://cdn.lytx.io/static%2Fsite.webmanifest" />
|
|
39
|
+
<link rel="mask-icon" href="https://cdn.lytx.io/static%2Fsafari-pinned-tab.svg" color="#5bbad5" />
|
|
40
|
+
<meta name="msapplication-TileColor" content="#da532c" />
|
|
41
|
+
<meta name="theme-color" content="#ffffff" />
|
|
42
|
+
<title>
|
|
43
|
+
${props.head && props.head.title ? props.head.title : "Lytx"}
|
|
44
|
+
</title>
|
|
45
|
+
|
|
46
|
+
</head>
|
|
47
|
+
<body>
|
|
48
|
+
${props.children}
|
|
49
|
+
</body>
|
|
50
|
+
</html> `;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* These are GDPR,CCPA Privacy compliant web events
|
|
3
|
+
*/
|
|
4
|
+
export interface WebEvent {
|
|
5
|
+
/**We track the page URL of each page view on your website.
|
|
6
|
+
* We use this to show you which pages have been viewed and how many
|
|
7
|
+
* times a particular page has been viewed.
|
|
8
|
+
|
|
9
|
+
* The hostname and path are collected.
|
|
10
|
+
* Query parameters are discarded, except for these special query parameters:
|
|
11
|
+
* ref=, source=, utm_source=, utm_medium=, utm_campaign=, utm_content= and utm_term=.
|
|
12
|
+
*/
|
|
13
|
+
page_url?: string;
|
|
14
|
+
/**
|
|
15
|
+
* We use the referrer string to show you the number of
|
|
16
|
+
* visitors referred to your website from links on other sites.
|
|
17
|
+
*/
|
|
18
|
+
referer?: string;
|
|
19
|
+
/**
|
|
20
|
+
* We use this to show you what browsers and browser version numbers
|
|
21
|
+
* people use when visiting your website.
|
|
22
|
+
* This is derived from the User-Agent HTTP header.
|
|
23
|
+
* The full User-Agent is discarded.
|
|
24
|
+
*/
|
|
25
|
+
browser?: string;
|
|
26
|
+
/**
|
|
27
|
+
* We use this to show you what operating systems people use when visiting your website.
|
|
28
|
+
* We show the brand of the operating system and the version number.
|
|
29
|
+
* This is derived from the User-Agent HTTP header.
|
|
30
|
+
* The full User-Agent is discarded.
|
|
31
|
+
*/
|
|
32
|
+
operating_system?: string;
|
|
33
|
+
/**
|
|
34
|
+
* We use this to show you what devices people use when visiting your website.
|
|
35
|
+
* Devices are categorized into desktop, mobile or tablet.
|
|
36
|
+
* This is derived from the User-Agent HTTP header.
|
|
37
|
+
* The full User-Agent is discarded.
|
|
38
|
+
*/
|
|
39
|
+
device_type?: string;
|
|
40
|
+
/**
|
|
41
|
+
* We look up the visitor’s location using their IP address.
|
|
42
|
+
* We do not track anything more granular than the city level
|
|
43
|
+
* and the IP address of the visitor is discarded.
|
|
44
|
+
* We never store IP addresses in our database or logs.
|
|
45
|
+
*/
|
|
46
|
+
country?: IncomingRequestCfProperties["country"];
|
|
47
|
+
region?: IncomingRequestCfProperties["region"];
|
|
48
|
+
city?: IncomingRequestCfProperties["city"];
|
|
49
|
+
postal?: IncomingRequestCfProperties["postalCode"];
|
|
50
|
+
/**
|
|
51
|
+
* Random string hash to count uniques
|
|
52
|
+
* Old salts are deleted every 24 hours to avoid the possibility of
|
|
53
|
+
* linking visitor information from one day to the next.
|
|
54
|
+
* Forgetting used salts also removes the possibility of the original
|
|
55
|
+
* IP addresses being revealed in a brute-force attack.
|
|
56
|
+
* The raw IP address and User-Agent are rendered completely inaccessible to anyone,
|
|
57
|
+
* including ourselves.
|
|
58
|
+
*
|
|
59
|
+
* hash(daily_salt + website_domain + ip_address + user_agent)
|
|
60
|
+
*/
|
|
61
|
+
rid?: string | null;
|
|
62
|
+
/**
|
|
63
|
+
* Page event
|
|
64
|
+
*/
|
|
65
|
+
event?: "page_view" | "form_fill" | "phone_call " | "screen_view";
|
|
66
|
+
tag_id?: string;
|
|
67
|
+
client_page_url?: string;
|
|
68
|
+
screen_width?: number;
|
|
69
|
+
screen_height?: number;
|
|
70
|
+
/**@deprecated**/
|
|
71
|
+
account_id?: number;
|
|
72
|
+
team_id?: number;
|
|
73
|
+
site_id?: number;
|
|
74
|
+
query_params?: Record<string, string>;
|
|
75
|
+
bot_data?: Record<string, string>;
|
|
76
|
+
custom_data?: Record<string, string>;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const blockedQueryParams = [
|
|
80
|
+
"order",
|
|
81
|
+
"email",
|
|
82
|
+
"credit",
|
|
83
|
+
"name",
|
|
84
|
+
"phone",
|
|
85
|
+
"number",
|
|
86
|
+
"user",
|
|
87
|
+
"pay",
|
|
88
|
+
"sha",
|
|
89
|
+
"card",
|
|
90
|
+
"credit",
|
|
91
|
+
"pass",
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
//Record<'custom',string>
|
|
95
|
+
|
|
96
|
+
//this function works on a website
|
|
97
|
+
|
|
98
|
+
//we need it to work on a tv
|
|
99
|
+
|
|
100
|
+
export type Platform = "tv" | "web" | "app" | "other";
|
|
101
|
+
|
|
102
|
+
type TrackEventPayload = Omit<WebEvent, "event"> & {
|
|
103
|
+
event?: WebEvent["event"] | Record<"custom", string>;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export function trackEvents(
|
|
107
|
+
account: string,
|
|
108
|
+
platformName: Platform = "web",
|
|
109
|
+
event: WebEvent["event"] | Record<"custom", string> | null = null,
|
|
110
|
+
macros: string,
|
|
111
|
+
customData?: Record<string, string>
|
|
112
|
+
) {
|
|
113
|
+
let data: TrackEventPayload = {};
|
|
114
|
+
const macrosObj: Record<string, string> = {};
|
|
115
|
+
const safeCustomData = customData && Object.keys(customData).length > 0
|
|
116
|
+
? customData
|
|
117
|
+
: undefined;
|
|
118
|
+
//if tv
|
|
119
|
+
if (platformName == "tv") {
|
|
120
|
+
//const macroUrl = new URL(`https://www.lytx.io?${macros}`);
|
|
121
|
+
const macrosArr = macros.split("&");
|
|
122
|
+
macrosArr.forEach((element) => {
|
|
123
|
+
const [key, value] = element.split("=");
|
|
124
|
+
macrosObj[key] = value;
|
|
125
|
+
});
|
|
126
|
+
data = {
|
|
127
|
+
custom_data: safeCustomData ?? (macrosObj || undefined),
|
|
128
|
+
client_page_url: macrosObj["client_page_url"] || undefined,
|
|
129
|
+
event: event ?? "screen_view",
|
|
130
|
+
screen_height:
|
|
131
|
+
Number(macrosObj["screen_height"].replace(/\D/g, "")) || undefined,
|
|
132
|
+
screen_width:
|
|
133
|
+
Number(macrosObj["screen_width"].replace(/\D/g, "")) || undefined,
|
|
134
|
+
rid: macrosObj["rid"] || undefined,
|
|
135
|
+
browser: macrosObj["browser"] || undefined,
|
|
136
|
+
operating_system: macrosObj["operatingSytem"] || undefined,
|
|
137
|
+
device_type: macrosObj["deviceType"] || undefined,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
data = {
|
|
142
|
+
referer: document.referrer,
|
|
143
|
+
event: event ?? "page_view",
|
|
144
|
+
client_page_url: window.location.href,
|
|
145
|
+
screen_height: window.screen.height,
|
|
146
|
+
screen_width: window.screen.width,
|
|
147
|
+
custom_data: safeCustomData,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
(async () => {
|
|
152
|
+
// __LYTX_DOMAIN__ is replaced at runtime by the tag API
|
|
153
|
+
const lytxDomain = "__LYTX_DOMAIN__";
|
|
154
|
+
const req = await window.fetch(
|
|
155
|
+
`${lytxDomain}/trackWebEvent.v2?account=${account}&platform=${platformName}`,
|
|
156
|
+
{
|
|
157
|
+
method: "POST",
|
|
158
|
+
body: JSON.stringify(data),
|
|
159
|
+
headers: {
|
|
160
|
+
"Content-Type": "application/json",
|
|
161
|
+
},
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
if (req.ok) {
|
|
166
|
+
const resp = await req.json() as { error: null | boolean, status: number, rid: string };
|
|
167
|
+
//console.log(resp);
|
|
168
|
+
if (window.lytxDataLayer && resp.rid) {
|
|
169
|
+
window.lytxDataLayer[0].rid = resp.rid;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// error: newEvent.error, status: newEvent.status, rid:ridVal
|
|
173
|
+
}
|
|
174
|
+
})();
|
|
175
|
+
|
|
176
|
+
//check platfrom
|
|
177
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
export type GoogleEvent = "phone_conversion_number" | "conversion";
|
|
2
|
+
export type GoogleCommand = "config" | "event" | "set" | "get" | "consent";
|
|
3
|
+
|
|
4
|
+
export type GoogleConversionParams = {
|
|
5
|
+
GoogleCommand: GoogleCommand;
|
|
6
|
+
id: string;
|
|
7
|
+
type: GoogleEvent;
|
|
8
|
+
value?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type googleParam = "config"
|
|
12
|
+
export type googleParamSlot2 = Date | string;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
export type gtag = (param: googleParam, param2: googleParamSlot2) => void;
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
export function googleTagScript(id: string) {
|
|
19
|
+
return {
|
|
20
|
+
async: true,
|
|
21
|
+
src: `https://www.googletagmanager.com/gtag/js?id=${id}`,
|
|
22
|
+
id: id,
|
|
23
|
+
callBack: (id: string) => {
|
|
24
|
+
window.dataLayer = window.dataLayer || [];
|
|
25
|
+
if (window.gtag_lytx) {
|
|
26
|
+
const gtag_lytx: gtag = function() {
|
|
27
|
+
window.dataLayer.push(arguments);
|
|
28
|
+
}
|
|
29
|
+
window.gtag_lytx = gtag_lytx;
|
|
30
|
+
gtag_lytx("config", new Date());
|
|
31
|
+
gtag_lytx("config", id);
|
|
32
|
+
} else {
|
|
33
|
+
const gtagScript = document.createElement('script');
|
|
34
|
+
|
|
35
|
+
gtagScript.innerHTML = `
|
|
36
|
+
window.dataLayer = window.dataLayer || [];
|
|
37
|
+
function gtag_lytx(){window.dataLayer.push(arguments);}
|
|
38
|
+
gtag_lytx('js', new Date());
|
|
39
|
+
|
|
40
|
+
gtag_lytx('config', '${id}');
|
|
41
|
+
`;
|
|
42
|
+
|
|
43
|
+
const scriptTags = document.head.querySelectorAll('script');
|
|
44
|
+
let scriptPlacement = document.head.children[0];
|
|
45
|
+
if (scriptTags) {
|
|
46
|
+
const scripts = [...scriptTags as any] as HTMLScriptElement[];
|
|
47
|
+
|
|
48
|
+
const activeGscript = scripts.filter((val) => val.src.includes(`id=${id}`));
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
scriptPlacement = activeGscript[0].nextSibling as Element;
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.log(error);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (!scriptPlacement) {
|
|
59
|
+
scriptPlacement = document.getElementsByTagName("script")[0];
|
|
60
|
+
}
|
|
61
|
+
scriptPlacement.parentNode!.insertBefore(gtagScript, scriptPlacement);
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
export function manualGoogleConversion(send_to: string, options?: Record<string, any>) {
|
|
70
|
+
function gtag_report_conversion(url: any) {
|
|
71
|
+
var callback = function() {
|
|
72
|
+
if (typeof (url) != 'undefined') {
|
|
73
|
+
window.location = url;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
window.gtag_lytx('event', 'conversion', {
|
|
77
|
+
'send_to': send_to,
|
|
78
|
+
'event_callback': callback,
|
|
79
|
+
...options,
|
|
80
|
+
});
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
//@ts-ignore
|
|
84
|
+
gtag_report_conversion();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
export function googleConversion(
|
|
89
|
+
GoogleCommand: GoogleCommand,
|
|
90
|
+
id: string,
|
|
91
|
+
type: GoogleEvent,
|
|
92
|
+
value?: string | number
|
|
93
|
+
) {
|
|
94
|
+
//@ts-ignore
|
|
95
|
+
const options: Record<GoogleEvent, any> = {};
|
|
96
|
+
|
|
97
|
+
if (GoogleCommand == "config") {
|
|
98
|
+
if (window.lytxApi.debugMode) { console.log("Google Event is : ", type, GoogleCommand, id, value) }
|
|
99
|
+
|
|
100
|
+
//?Add groups for GA4 configs
|
|
101
|
+
options[`${type}`] = value;
|
|
102
|
+
try {
|
|
103
|
+
if (window.gtag_lytx) {
|
|
104
|
+
window.gtag_lytx(GoogleCommand, id, options);
|
|
105
|
+
} else {
|
|
106
|
+
const gtagScript = document.createElement('script');
|
|
107
|
+
gtagScript.innerHTML = `
|
|
108
|
+
gtag_lytx('${GoogleCommand}', '${id}', {
|
|
109
|
+
'${type}': '${value}'
|
|
110
|
+
});
|
|
111
|
+
`;
|
|
112
|
+
let scriptPlacement = document.head.children[0];
|
|
113
|
+
if (!scriptPlacement) {
|
|
114
|
+
scriptPlacement = document.getElementsByTagName("script")[0];
|
|
115
|
+
}
|
|
116
|
+
scriptPlacement.parentNode!.insertBefore(gtagScript, scriptPlacement);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.log(error);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else if (GoogleCommand == "event") {
|
|
124
|
+
if (window.lytxApi.debugMode) { console.log("Google Event is : ", type, GoogleCommand, id, value) }
|
|
125
|
+
if (type == "conversion") {
|
|
126
|
+
manualGoogleConversion(id, { value: value });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
function googleClickConversion(elems: NodeListOf<HTMLElement>, parsedValue: {
|
|
135
|
+
GoogleCommand: GoogleCommand;
|
|
136
|
+
id: string;
|
|
137
|
+
type: GoogleEvent;
|
|
138
|
+
value?: string | undefined;
|
|
139
|
+
}[]) {
|
|
140
|
+
elems.forEach((elem) => {
|
|
141
|
+
elem.addEventListener("click", () => {
|
|
142
|
+
|
|
143
|
+
parsedValue.forEach((val) =>
|
|
144
|
+
googleConversion(
|
|
145
|
+
val.GoogleCommand,
|
|
146
|
+
val.id,
|
|
147
|
+
val.type,
|
|
148
|
+
val.value
|
|
149
|
+
)
|
|
150
|
+
);
|
|
151
|
+
});
|
|
152
|
+
})
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function googleSingleClickConversion(elem: Element, parsedValue: {
|
|
156
|
+
GoogleCommand: GoogleCommand;
|
|
157
|
+
id: string;
|
|
158
|
+
type: GoogleEvent;
|
|
159
|
+
value?: string | undefined;
|
|
160
|
+
}[]) {
|
|
161
|
+
|
|
162
|
+
elem.addEventListener("click", () => {
|
|
163
|
+
|
|
164
|
+
parsedValue.forEach((val) =>
|
|
165
|
+
googleConversion(
|
|
166
|
+
val.GoogleCommand,
|
|
167
|
+
val.id,
|
|
168
|
+
val.type,
|
|
169
|
+
val.value
|
|
170
|
+
)
|
|
171
|
+
);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function linkedinScript(id: string) {
|
|
2
|
+
|
|
3
|
+
const _linkedin_partner_id = id;
|
|
4
|
+
window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];
|
|
5
|
+
window._linkedin_data_partner_ids.push(_linkedin_partner_id);
|
|
6
|
+
|
|
7
|
+
(function(l) {
|
|
8
|
+
if (!l) {
|
|
9
|
+
//@ts-expect-error
|
|
10
|
+
window.lintrk = function(a, b) { window.lintrk.q.push([a, b]) };
|
|
11
|
+
//@ts-expect-error
|
|
12
|
+
window.lintrk.q = []
|
|
13
|
+
}
|
|
14
|
+
var s = document.getElementsByTagName("script")[0];
|
|
15
|
+
var b = document.createElement("script");
|
|
16
|
+
b.type = "text/javascript"; b.async = true;
|
|
17
|
+
b.src = "https://snap.licdn.com/li.lms-analytics/insight.min.js";
|
|
18
|
+
//@ts-expect-error
|
|
19
|
+
s.parentNode.insertBefore(b, s);
|
|
20
|
+
})(window.lintrk);
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export function metaScript(config: { metaId?: string, eventName?: string, scriptInit?: boolean }) {
|
|
2
|
+
const { metaId, eventName, scriptInit } = config;
|
|
3
|
+
let init = scriptInit ?? false;
|
|
4
|
+
let event = eventName ?? "PageView";
|
|
5
|
+
let id = metaId ?? "";
|
|
6
|
+
const facebookPixelStandardEvents = [
|
|
7
|
+
"AddPaymentInfo",
|
|
8
|
+
"AddToCart",
|
|
9
|
+
"AddToWishlist",
|
|
10
|
+
"CompleteRegistration",
|
|
11
|
+
"Contact",
|
|
12
|
+
"CustomizeProduct",
|
|
13
|
+
"Donate",
|
|
14
|
+
"FindLocation",
|
|
15
|
+
"InitiateCheckout",
|
|
16
|
+
"Lead",
|
|
17
|
+
"PageView",
|
|
18
|
+
"Purchase",
|
|
19
|
+
"Schedule",
|
|
20
|
+
"Search",
|
|
21
|
+
"StartTrial",
|
|
22
|
+
"SubmitApplication",
|
|
23
|
+
"Subscribe",
|
|
24
|
+
"ViewContent"
|
|
25
|
+
];
|
|
26
|
+
if (init) {
|
|
27
|
+
//@ts-expect-error
|
|
28
|
+
!function(f, b, e, v, n, t, s) {
|
|
29
|
+
//@ts-expect-error
|
|
30
|
+
if (f.fbq) return; n = f.fbq = function() {
|
|
31
|
+
//@ts-expect-error
|
|
32
|
+
n.callMethod ?
|
|
33
|
+
//@ts-expect-error
|
|
34
|
+
n.callMethod.apply(n, arguments) : n.queue.push(arguments)
|
|
35
|
+
};
|
|
36
|
+
//@ts-expect-error
|
|
37
|
+
if (!f._fbq) f._fbq = n; n.push = n; n.loaded = !0; n.version = '2.0';
|
|
38
|
+
//@ts-expect-error
|
|
39
|
+
n.queue = []; t = b.createElement(e); t.async = !0;
|
|
40
|
+
//@ts-expect-error
|
|
41
|
+
t.src = v; s = b.getElementsByTagName(e)[0];
|
|
42
|
+
//@ts-expect-error
|
|
43
|
+
s.parentNode.insertBefore(t, s)
|
|
44
|
+
}(window, document, 'script',
|
|
45
|
+
'https://connect.facebook.net/en_US/fbevents.js');
|
|
46
|
+
}
|
|
47
|
+
if (window.fbq) {
|
|
48
|
+
if (init) { window.fbq('init', `${id}`); }
|
|
49
|
+
if (facebookPixelStandardEvents.includes(event)) {
|
|
50
|
+
window.fbq('track', event);
|
|
51
|
+
} else {
|
|
52
|
+
window.fbq('trackCustom', event);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function quantcastScript(label?: string) {
|
|
2
|
+
return {
|
|
3
|
+
async: true,
|
|
4
|
+
src: (document.location.protocol == "https:" ? "https://secure" : "http://edge") + ".quantserve.com/quant.js",
|
|
5
|
+
element: "script",
|
|
6
|
+
callBack: (id: string) => {
|
|
7
|
+
window._qevents = window._qevents || [];
|
|
8
|
+
if (window.lytxApi.debugMode) {
|
|
9
|
+
console.log('Quantcast label is : ', label);
|
|
10
|
+
}
|
|
11
|
+
const qStructure = {
|
|
12
|
+
"qacct": id,
|
|
13
|
+
"labels": label ?? "_fp.event.PageView"
|
|
14
|
+
}
|
|
15
|
+
if (label) {
|
|
16
|
+
//@ts-expect-error
|
|
17
|
+
qStructure.event = "refresh";
|
|
18
|
+
}
|
|
19
|
+
window._qevents.push(qStructure);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { RequestInfo } from "rwsdk/worker";
|
|
2
|
+
import type { AuthUserSession } from "@lib/auth";
|
|
3
|
+
import type { DBAdapter, UserRole } from "@db/types";
|
|
4
|
+
import type { SitesContext, TeamContext } from "@db/d1/sites";
|
|
5
|
+
|
|
6
|
+
export type AppContext = {
|
|
7
|
+
session: AuthUserSession;
|
|
8
|
+
initial_site_setup: boolean;
|
|
9
|
+
sites: SitesContext | null;
|
|
10
|
+
team: TeamContext;
|
|
11
|
+
blink_id: string;
|
|
12
|
+
user_role: UserRole;
|
|
13
|
+
db_adapter: DBAdapter;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type AppRequestInfo = RequestInfo<any, AppContext>;
|