@d8a-tech/gd 0.35.1 → 0.36.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/README.md +17 -0
- package/dist/gd.js +68 -32
- package/dist/gd.js.map +2 -2
- package/dist/gd.min.js +5 -5
- package/dist/gd.min.js.map +2 -2
- package/package.json +1 -1
- package/src.hash +1 -1
package/README.md
CHANGED
|
@@ -12,6 +12,23 @@ Supported interception methods:
|
|
|
12
12
|
- navigator.sendBeacon calls
|
|
13
13
|
- Script tag loads
|
|
14
14
|
|
|
15
|
+
## Duplicate requests and cookies
|
|
16
|
+
|
|
17
|
+
Duplicated requests made with `fetch` also send cookies. This helps features like server-side
|
|
18
|
+
Google Tag Manager debug mode work when your duplicate endpoint needs those cookies.
|
|
19
|
+
|
|
20
|
+
Notes:
|
|
21
|
+
- When the original request uses `navigator.sendBeacon` and `convert_to_get` is `false`, duplicate
|
|
22
|
+
requests will also use `sendBeacon` (which cannot send cookies). Use `convert_to_get: true`
|
|
23
|
+
to send beacon duplicates via `fetch` with cookies included.
|
|
24
|
+
- For cross-origin duplicate endpoints, your server must support credentialed CORS:
|
|
25
|
+
- `Access-Control-Allow-Origin` must be an explicit origin (not `*`).
|
|
26
|
+
- `Access-Control-Allow-Credentials` must be `true`.
|
|
27
|
+
- If credentialed CORS is not allowed by the endpoint, browsers can fail duplicate requests due to
|
|
28
|
+
CORS policy.
|
|
29
|
+
- Only configure trusted destination endpoints you control, because credentialed requests may send
|
|
30
|
+
cookies scoped to that destination origin.
|
|
31
|
+
|
|
15
32
|
## Usage
|
|
16
33
|
|
|
17
34
|
Include the built script in your HTML and initialize the duplicator:
|
package/dist/gd.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/* ga4-duplicator - built 2026-02-
|
|
1
|
+
/* ga4-duplicator - built 2026-02-20T20:15:46.018Z */
|
|
2
2
|
"use strict";
|
|
3
3
|
(() => {
|
|
4
4
|
// src/version.ts
|
|
5
|
-
var version = "v0.
|
|
5
|
+
var version = "v0.36.0" ? "v0.36.0" : devVersionUtc();
|
|
6
6
|
|
|
7
7
|
// src/ga4-duplicator.ts
|
|
8
8
|
window.createGA4Duplicator = function(options) {
|
|
@@ -31,7 +31,11 @@
|
|
|
31
31
|
const duplicateUrl = ctx.buildDuplicateUrl(requestUrl);
|
|
32
32
|
const convertToGet = ctx.getConvertToGet(requestUrl);
|
|
33
33
|
if (upperMethod === "GET") {
|
|
34
|
-
originalFetch(duplicateUrl, {
|
|
34
|
+
originalFetch(duplicateUrl, {
|
|
35
|
+
method: "GET",
|
|
36
|
+
keepalive: true,
|
|
37
|
+
credentials: "include"
|
|
38
|
+
}).catch((error) => {
|
|
35
39
|
if (ctx.debug) console.error("gtm interceptor: error duplicating GET fetch:", error);
|
|
36
40
|
});
|
|
37
41
|
} else if (upperMethod === "POST") {
|
|
@@ -44,7 +48,8 @@
|
|
|
44
48
|
originalFetch(duplicateUrl, {
|
|
45
49
|
method: "POST",
|
|
46
50
|
body: dupBody,
|
|
47
|
-
keepalive: true
|
|
51
|
+
keepalive: true,
|
|
52
|
+
credentials: "include"
|
|
48
53
|
}).catch((error) => {
|
|
49
54
|
if (ctx.debug)
|
|
50
55
|
console.error(
|
|
@@ -61,20 +66,26 @@
|
|
|
61
66
|
if (line) {
|
|
62
67
|
const mergedUrl = ctx.buildDuplicateUrl(requestUrl);
|
|
63
68
|
const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);
|
|
64
|
-
originalFetch(urlWithMergedLine, {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
originalFetch(urlWithMergedLine, {
|
|
70
|
+
method: "GET",
|
|
71
|
+
keepalive: true,
|
|
72
|
+
credentials: "include"
|
|
73
|
+
}).catch((error) => {
|
|
74
|
+
if (ctx.debug)
|
|
75
|
+
console.error(
|
|
76
|
+
"gtm interceptor: error duplicating GET fetch (from convert_to_get):",
|
|
77
|
+
error
|
|
78
|
+
);
|
|
79
|
+
});
|
|
73
80
|
sentAny = true;
|
|
74
81
|
}
|
|
75
82
|
}
|
|
76
83
|
if (!sentAny) {
|
|
77
|
-
originalFetch(duplicateUrl, {
|
|
84
|
+
originalFetch(duplicateUrl, {
|
|
85
|
+
method: "GET",
|
|
86
|
+
keepalive: true,
|
|
87
|
+
credentials: "include"
|
|
88
|
+
}).catch((error) => {
|
|
78
89
|
if (ctx.debug)
|
|
79
90
|
console.error(
|
|
80
91
|
"gtm interceptor: error duplicating GET fetch (empty body convert_to_get):",
|
|
@@ -86,7 +97,8 @@
|
|
|
86
97
|
originalFetch(duplicateUrl, {
|
|
87
98
|
method: "POST",
|
|
88
99
|
body: dupBody,
|
|
89
|
-
keepalive: true
|
|
100
|
+
keepalive: true,
|
|
101
|
+
credentials: "include"
|
|
90
102
|
}).catch((error) => {
|
|
91
103
|
if (ctx.debug)
|
|
92
104
|
console.error("gtm interceptor: error duplicating POST fetch:", error);
|
|
@@ -117,7 +129,11 @@
|
|
|
117
129
|
const duplicateUrl = ctx.buildDuplicateUrl(this._requestUrl);
|
|
118
130
|
const convertToGet = ctx.getConvertToGet(this._requestUrl);
|
|
119
131
|
if (method === "GET") {
|
|
120
|
-
fetch(duplicateUrl, {
|
|
132
|
+
fetch(duplicateUrl, {
|
|
133
|
+
method: "GET",
|
|
134
|
+
keepalive: true,
|
|
135
|
+
credentials: "include"
|
|
136
|
+
}).catch((error) => {
|
|
121
137
|
if (ctx.debug) console.error("gtm interceptor: error duplicating GET xhr:", error);
|
|
122
138
|
});
|
|
123
139
|
} else if (method === "POST") {
|
|
@@ -139,7 +155,11 @@
|
|
|
139
155
|
if (line) {
|
|
140
156
|
const mergedUrl = ctx.buildDuplicateUrl(this._requestUrl);
|
|
141
157
|
const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);
|
|
142
|
-
fetch(urlWithMergedLine, {
|
|
158
|
+
fetch(urlWithMergedLine, {
|
|
159
|
+
method: "GET",
|
|
160
|
+
keepalive: true,
|
|
161
|
+
credentials: "include"
|
|
162
|
+
}).catch((error) => {
|
|
143
163
|
if (ctx.debug)
|
|
144
164
|
console.error(
|
|
145
165
|
"gtm interceptor: error duplicating GET xhr (from convert_to_get):",
|
|
@@ -150,7 +170,11 @@
|
|
|
150
170
|
}
|
|
151
171
|
}
|
|
152
172
|
if (!sentAny) {
|
|
153
|
-
fetch(duplicateUrl, {
|
|
173
|
+
fetch(duplicateUrl, {
|
|
174
|
+
method: "GET",
|
|
175
|
+
keepalive: true,
|
|
176
|
+
credentials: "include"
|
|
177
|
+
}).catch((error) => {
|
|
154
178
|
if (ctx.debug)
|
|
155
179
|
console.error(
|
|
156
180
|
"gtm interceptor: error duplicating GET xhr (empty body convert_to_get):",
|
|
@@ -159,12 +183,15 @@
|
|
|
159
183
|
});
|
|
160
184
|
}
|
|
161
185
|
} else {
|
|
162
|
-
fetch(duplicateUrl, {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
)
|
|
186
|
+
fetch(duplicateUrl, {
|
|
187
|
+
method: "POST",
|
|
188
|
+
body,
|
|
189
|
+
keepalive: true,
|
|
190
|
+
credentials: "include"
|
|
191
|
+
}).catch((error) => {
|
|
192
|
+
if (ctx.debug)
|
|
193
|
+
console.error("gtm interceptor: error duplicating POST xhr:", error);
|
|
194
|
+
});
|
|
168
195
|
}
|
|
169
196
|
}
|
|
170
197
|
} catch (dupErr) {
|
|
@@ -204,7 +231,11 @@
|
|
|
204
231
|
if (line) {
|
|
205
232
|
const mergedUrl = ctx.buildDuplicateUrl(url);
|
|
206
233
|
const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);
|
|
207
|
-
fetch(urlWithMergedLine, {
|
|
234
|
+
fetch(urlWithMergedLine, {
|
|
235
|
+
method: "GET",
|
|
236
|
+
keepalive: true,
|
|
237
|
+
credentials: "include"
|
|
238
|
+
}).catch((error) => {
|
|
208
239
|
if (ctx.debug)
|
|
209
240
|
console.error(
|
|
210
241
|
"gtm interceptor: error duplicating GET beacon (from convert_to_get):",
|
|
@@ -215,7 +246,11 @@
|
|
|
215
246
|
}
|
|
216
247
|
}
|
|
217
248
|
if (!sentAny) {
|
|
218
|
-
fetch(duplicateUrl, {
|
|
249
|
+
fetch(duplicateUrl, {
|
|
250
|
+
method: "GET",
|
|
251
|
+
keepalive: true,
|
|
252
|
+
credentials: "include"
|
|
253
|
+
}).catch((error) => {
|
|
219
254
|
if (ctx.debug)
|
|
220
255
|
console.error(
|
|
221
256
|
"gtm interceptor: error duplicating GET beacon (empty body convert_to_get):",
|
|
@@ -248,12 +283,13 @@
|
|
|
248
283
|
const duplicateIfGA4Url = (urlString) => {
|
|
249
284
|
try {
|
|
250
285
|
if (!ctx.isTargetUrl(urlString)) return;
|
|
251
|
-
fetch(ctx.buildDuplicateUrl(urlString), {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
286
|
+
fetch(ctx.buildDuplicateUrl(urlString), {
|
|
287
|
+
method: "GET",
|
|
288
|
+
keepalive: true,
|
|
289
|
+
credentials: "include"
|
|
290
|
+
}).catch((error) => {
|
|
291
|
+
if (ctx.debug) console.error("gtm interceptor: error duplicating script GET:", error);
|
|
292
|
+
});
|
|
257
293
|
} catch (e) {
|
|
258
294
|
}
|
|
259
295
|
};
|
package/dist/gd.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/version.ts", "../src/ga4-duplicator.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Package version identifier.\n * This value is replaced at build time via esbuild define.\n */\ndeclare const __D8A_VERSION__: string;\n\nfunction devVersionUtc(): string {\n const now = new Date();\n const year = String(now.getUTCFullYear()).slice(-2);\n const month = String(now.getUTCMonth() + 1).padStart(2, \"0\");\n return `dev-${year}-${month}`;\n}\n\nexport const version: string =\n typeof __D8A_VERSION__ !== \"undefined\" && __D8A_VERSION__ ? __D8A_VERSION__ : devVersionUtc();\n", "/**\n * GA4 Duplicator - Intercepts GA4 collect calls and sends duplicates to D8A.\n */\n\nimport { version } from \"./version\";\n\ninterface GA4Destination {\n measurement_id: string;\n server_container_url: string;\n convert_to_get?: boolean;\n}\n\ninterface GA4DuplicatorOptions {\n server_container_url?: string;\n destinations?: GA4Destination[];\n debug?: boolean;\n convert_to_get?: boolean;\n}\n\n(window as any).createGA4Duplicator = function (options: GA4DuplicatorOptions) {\n /**\n * Shared logic and configuration for interceptors.\n */\n interface InterceptorContext {\n debug: boolean;\n isTargetUrl(url: string | null | undefined): boolean;\n buildDuplicateUrl(url: string): string;\n getConvertToGet(url: string): boolean;\n }\n\n /**\n * Base interface for monkey-patching implementations.\n */\n interface NetworkInterceptor {\n install(context: InterceptorContext): void;\n }\n\n class FetchInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n const originalFetch = window.fetch;\n window.fetch = function (\n this: any,\n resource: RequestInfo | URL,\n config?: RequestInit,\n ): Promise<Response> {\n const requestUrl =\n typeof resource === \"string\"\n ? resource\n : resource instanceof URL\n ? resource.toString()\n : (resource as any).url;\n const method = (config && config.method) || (resource as any).method || \"GET\";\n\n if (ctx.isTargetUrl(requestUrl)) {\n const upperMethod = (method || \"GET\").toUpperCase();\n\n // If we need the body from a Request, clone BEFORE calling the original fetch\n let prepareBodyPromise: Promise<any> = Promise.resolve(undefined);\n if (upperMethod === \"POST\") {\n if (config && Object.prototype.hasOwnProperty.call(config, \"body\")) {\n prepareBodyPromise = Promise.resolve(config.body);\n } else if (typeof Request !== \"undefined\" && resource instanceof Request) {\n try {\n const clonedReq = resource.clone();\n prepareBodyPromise = clonedReq.blob().catch(() => undefined);\n } catch {\n prepareBodyPromise = Promise.resolve(undefined);\n }\n }\n }\n\n // First send original request to Google Analytics\n const originalPromise = originalFetch.apply(this, arguments as any);\n\n // Then send duplicate\n const duplicateUrl = ctx.buildDuplicateUrl(requestUrl);\n const convertToGet = ctx.getConvertToGet(requestUrl);\n\n if (upperMethod === \"GET\") {\n originalFetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating GET fetch:\", error);\n });\n } else if (upperMethod === \"POST\") {\n prepareBodyPromise.then((dupBody) => {\n if (convertToGet) {\n // Convert POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof dupBody === \"string\") {\n bodyStr = dupBody;\n } else if (dupBody instanceof Blob) {\n // For blob, we can't easily convert synchronously, so fall back to POST\n originalFetch(duplicateUrl, {\n method: \"POST\",\n body: dupBody,\n keepalive: true,\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating POST fetch (convert_to_get with Blob):\",\n error,\n );\n });\n return;\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(requestUrl);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n originalFetch(urlWithMergedLine, { method: \"GET\", keepalive: true }).catch(\n (error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET fetch (from convert_to_get):\",\n error,\n );\n },\n );\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n originalFetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET fetch (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original POST duplication\n originalFetch(duplicateUrl, {\n method: \"POST\",\n body: dupBody,\n keepalive: true,\n }).catch((error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating POST fetch:\", error);\n });\n }\n });\n }\n\n return originalPromise;\n }\n\n return originalFetch.apply(this, arguments as any);\n };\n }\n }\n\n class XhrInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n const originalXHROpen = XMLHttpRequest.prototype.open;\n const originalXHRSend = XMLHttpRequest.prototype.send;\n\n XMLHttpRequest.prototype.open = function (this: any, method: string, url: string | URL) {\n this._requestMethod = method;\n this._requestUrl = url;\n return originalXHROpen.apply(this, arguments as any);\n };\n\n XMLHttpRequest.prototype.send = function (\n this: any,\n body?: Document | XMLHttpRequestBodyInit | null,\n ) {\n if (this._requestUrl && ctx.isTargetUrl(this._requestUrl)) {\n // First send original request to Google Analytics\n const originalResult = originalXHRSend.apply(this, arguments as any);\n\n // Then send duplicate to our endpoint mimicking method and payload\n try {\n const method = (this._requestMethod || \"GET\").toUpperCase();\n const duplicateUrl = ctx.buildDuplicateUrl(this._requestUrl);\n const convertToGet = ctx.getConvertToGet(this._requestUrl);\n\n if (method === \"GET\") {\n fetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating GET xhr:\", error);\n });\n } else if (method === \"POST\") {\n if (convertToGet) {\n // Convert POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof body === \"string\") {\n bodyStr = body;\n } else if (body && typeof body === \"object\") {\n // Try to convert Document or other types to string\n try {\n bodyStr = String(body);\n } catch {\n bodyStr = \"\";\n }\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(this._requestUrl);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n fetch(urlWithMergedLine, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET xhr (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n fetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET xhr (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original POST duplication\n fetch(duplicateUrl, { method: \"POST\", body: body as any, keepalive: true }).catch(\n (error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating POST xhr:\", error);\n },\n );\n }\n }\n } catch (dupErr) {\n if (ctx.debug) console.error(\"gtm interceptor: xhr duplication failed:\", dupErr);\n }\n return originalResult;\n }\n return originalXHRSend.apply(this, arguments as any);\n };\n }\n }\n\n class BeaconInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n if (!navigator.sendBeacon) return;\n\n const originalSendBeacon = navigator.sendBeacon;\n navigator.sendBeacon = function (\n this: any,\n url: string | URL,\n data?: BodyInit | null,\n ): boolean {\n if (ctx.isTargetUrl(url as string)) {\n const originalResult = originalSendBeacon.apply(this, arguments as any);\n try {\n const duplicateUrl = ctx.buildDuplicateUrl(url as string);\n const convertToGet = ctx.getConvertToGet(url as string);\n\n if (convertToGet) {\n // Convert sendBeacon POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof data === \"string\") {\n bodyStr = data;\n } else if (data && typeof data === \"object\") {\n try {\n bodyStr = String(data);\n } catch {\n bodyStr = \"\";\n }\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(url as string);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n fetch(urlWithMergedLine, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET beacon (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n fetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET beacon (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original sendBeacon duplication\n originalSendBeacon.call(navigator, duplicateUrl, data);\n }\n } catch (e) {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating sendBeacon:\", e);\n }\n return originalResult;\n }\n return originalSendBeacon.apply(this, arguments as any);\n };\n }\n }\n\n class ScriptInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n try {\n const scriptSrcDescriptor = Object.getOwnPropertyDescriptor(\n HTMLScriptElement.prototype,\n \"src\",\n );\n const originalScriptSrcSetter = scriptSrcDescriptor && scriptSrcDescriptor.set;\n const originalScriptSrcGetter = scriptSrcDescriptor && scriptSrcDescriptor.get;\n const originalScriptSetAttribute = HTMLScriptElement.prototype.setAttribute;\n\n const duplicateIfGA4Url = (urlString: string) => {\n try {\n if (!ctx.isTargetUrl(urlString)) return;\n fetch(ctx.buildDuplicateUrl(urlString), { method: \"GET\", keepalive: true }).catch(\n (error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating script GET:\", error);\n },\n );\n } catch {\n // Intentionally empty\n }\n };\n\n if (originalScriptSrcSetter && originalScriptSrcGetter) {\n const setter = originalScriptSrcSetter;\n const getter = originalScriptSrcGetter;\n Object.defineProperty(HTMLScriptElement.prototype, \"src\", {\n configurable: true,\n enumerable: true,\n get: function (this: any) {\n return getter.call(this);\n },\n set: function (this: any, value: string) {\n try {\n const last = this.__ga4LastSrcDuplicated;\n if (value && value !== last) {\n duplicateIfGA4Url(String(value));\n this.__ga4LastSrcDuplicated = String(value);\n }\n const self = this;\n const onloadOnce = function () {\n try {\n const finalUrl = self.src;\n if (finalUrl && finalUrl !== self.__ga4LastSrcDuplicated) {\n duplicateIfGA4Url(finalUrl);\n self.__ga4LastSrcDuplicated = finalUrl;\n }\n } catch {}\n self.removeEventListener(\"load\", onloadOnce);\n };\n this.addEventListener(\"load\", onloadOnce);\n } catch {}\n setter.call(this, value);\n },\n });\n }\n\n HTMLScriptElement.prototype.setAttribute = function (\n this: any,\n name: string,\n value: string,\n ) {\n try {\n if (String(name).toLowerCase() === \"src\") {\n const v = String(value);\n const last = this.__ga4LastSrcDuplicated;\n if (v && v !== last) {\n duplicateIfGA4Url(v);\n this.__ga4LastSrcDuplicated = v;\n }\n const selfAttr = this;\n const onloadOnceAttr = function () {\n try {\n const finalUrlAttr = selfAttr.src;\n if (finalUrlAttr && finalUrlAttr !== selfAttr.__ga4LastSrcDuplicated) {\n duplicateIfGA4Url(finalUrlAttr);\n selfAttr.__ga4LastSrcDuplicated = finalUrlAttr;\n }\n } catch {}\n selfAttr.removeEventListener(\"load\", onloadOnceAttr);\n };\n this.addEventListener(\"load\", onloadOnceAttr);\n }\n } catch {\n // Intentionally empty\n }\n return originalScriptSetAttribute.apply(this, arguments as any);\n };\n } catch {}\n }\n }\n\n if ((window as any).__ga4DuplicatorInitialized) {\n if (options.debug) console.warn(\"GA4 Duplicator: already initialized.\");\n return;\n }\n\n const destinations: GA4Destination[] = [];\n if (options.destinations && Array.isArray(options.destinations)) {\n for (let i = 0; i < options.destinations.length; i++) {\n const dest = options.destinations[i];\n destinations.push({\n measurement_id: dest.measurement_id,\n server_container_url: dest.server_container_url,\n convert_to_get:\n dest.convert_to_get !== undefined ? dest.convert_to_get : options.convert_to_get,\n });\n }\n }\n\n if (options.server_container_url) {\n destinations.push({\n measurement_id: \"*\",\n server_container_url: options.server_container_url,\n convert_to_get: options.convert_to_get,\n });\n }\n\n if (destinations.length === 0) {\n console.error(\"GA4 Duplicator: either server_container_url or destinations array is required\");\n return;\n }\n\n function normalizePath(p: string): string {\n p = String(p || \"\");\n p = p.replace(/\\/+$/, \"\");\n return p === \"\" ? \"/\" : p;\n }\n\n function matchesId(pattern: string, id: string): boolean {\n if (!pattern || pattern === \"*\") return true;\n try {\n const regexStr = pattern.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\*/g, \".*\");\n return new RegExp(\"^\" + regexStr + \"$\", \"i\").test(id);\n } catch {\n return pattern.toLowerCase() === id.toLowerCase();\n }\n }\n\n function ensureBareQueryFlag(url: string, flag: string): string {\n const u = String(url || \"\");\n const f = String(flag || \"\").trim();\n if (!u || !f) return u;\n\n // Keep fragment intact\n const hashIdx = u.indexOf(\"#\");\n const beforeHash = hashIdx >= 0 ? u.slice(0, hashIdx) : u;\n const hash = hashIdx >= 0 ? u.slice(hashIdx) : \"\";\n\n const qIdx = beforeHash.indexOf(\"?\");\n const base = qIdx >= 0 ? beforeHash.slice(0, qIdx) : beforeHash;\n const rawQuery = qIdx >= 0 ? beforeHash.slice(qIdx + 1) : \"\";\n\n const parts = rawQuery\n ? rawQuery\n .split(\"&\")\n .map((p) => p.trim())\n .filter(Boolean)\n : [];\n\n const kept: string[] = [];\n for (let i = 0; i < parts.length; i++) {\n const p = parts[i];\n if (p === f) continue;\n if (p.startsWith(f + \"=\")) continue;\n kept.push(p);\n }\n\n const newQuery = kept.length > 0 ? kept.join(\"&\") + \"&\" + f : f;\n return base + \"?\" + newQuery + hash;\n }\n\n function getMeasurementId(url: string): string {\n try {\n const parsed = new URL(url, location.href);\n return parsed.searchParams.get(\"tid\") || parsed.searchParams.get(\"id\") || \"\";\n } catch {\n const match = url.match(/[?&](?:tid|id)=([^&?#]+)/);\n return match ? decodeURIComponent(match[1]) : \"\";\n }\n }\n\n function getDestinationForId(id: string): GA4Destination | null {\n for (let i = 0; i < destinations.length; i++) {\n if (matchesId(destinations[i].measurement_id, id)) {\n return destinations[i];\n }\n }\n return null;\n }\n\n function mergeBodyLineWithUrl(originalUrl: string, bodyLine: string): string {\n try {\n const url = new URL(originalUrl, location.href);\n const lineParams = new URLSearchParams(bodyLine);\n\n // Line parameters override URL parameters\n for (const [key] of lineParams.entries()) {\n url.searchParams.delete(key);\n }\n for (const [key, value] of lineParams.entries()) {\n url.searchParams.append(key, value);\n }\n\n return ensureBareQueryFlag(url.toString(), \"richsstsse\");\n } catch {\n // Fallback: if URL parsing fails, try string manipulation\n const urlWithoutQuery = originalUrl.split(\"?\")[0];\n const originalParams = originalUrl.match(/\\?(.*)/) ? originalUrl.match(/\\?(.*)/)![1] : \"\";\n const merged = originalParams + (originalParams && bodyLine ? \"&\" : \"\") + bodyLine;\n return ensureBareQueryFlag(urlWithoutQuery + (merged ? \"?\" + merged : \"\"), \"richsstsse\");\n }\n }\n\n function getDuplicateEndpointUrl(dest: GA4Destination): URL {\n const trackingURL = String(dest.server_container_url || \"\").trim();\n const u = new URL(trackingURL, location.href);\n u.search = \"\";\n u.hash = \"\";\n return u;\n }\n\n function isTargetUrl(url: string | null | undefined): boolean {\n if (!url || typeof url !== \"string\") return false;\n try {\n const parsed = new URL(url, location.href);\n\n for (let i = 0; i < destinations.length; i++) {\n const duplicateTarget = getDuplicateEndpointUrl(destinations[i]);\n if (\n parsed.origin === duplicateTarget.origin &&\n normalizePath(parsed.pathname) === normalizePath(duplicateTarget.pathname)\n ) {\n return false;\n }\n }\n\n const params = parsed.searchParams;\n const hasGtm = params.has(\"gtm\");\n const hasTagExp = params.has(\"tag_exp\");\n const measurementId = params.get(\"tid\") || params.get(\"id\") || \"\";\n const isMeasurementIdGA4 = /^G-[A-Z0-9]+$/i.test(measurementId);\n\n return hasGtm && hasTagExp && isMeasurementIdGA4;\n } catch {\n if (typeof url === \"string\") {\n for (let j = 0; j < destinations.length; j++) {\n try {\n const target = getDuplicateEndpointUrl(destinations[j]);\n const targetNoQuery = target.origin + target.pathname;\n if (url.indexOf(targetNoQuery) !== -1) return false;\n } catch {\n // Intentionally empty\n }\n }\n\n const hasGtmFallback = url.indexOf(\"gtm=\") !== -1;\n const hasTagExpFallback = url.indexOf(\"tag_exp=\") !== -1;\n const idMatch = url.match(/[?&](?:tid|id)=G-[A-Za-z0-9]+/);\n return !!(hasGtmFallback && hasTagExpFallback && idMatch);\n }\n return false;\n }\n }\n\n function buildDuplicateUrl(originalUrl: string): string {\n const id = getMeasurementId(originalUrl);\n const dest = getDestinationForId(id);\n if (!dest) return \"\";\n\n const dst = getDuplicateEndpointUrl(dest);\n try {\n const src = new URL(originalUrl, location.href);\n dst.search = src.search;\n dst.searchParams.set(\"_dtv\", version);\n dst.searchParams.set(\"_dtn\", \"gd\");\n } catch {}\n return ensureBareQueryFlag(dst.toString(), \"richsstsse\");\n }\n\n function getConvertToGet(url: string): boolean {\n const id = getMeasurementId(url);\n const dest = getDestinationForId(id);\n return dest ? !!dest.convert_to_get : false;\n }\n\n const context: InterceptorContext = {\n debug: !!options.debug,\n isTargetUrl,\n buildDuplicateUrl,\n getConvertToGet,\n };\n\n const interceptors: NetworkInterceptor[] = [\n new FetchInterceptor(),\n new XhrInterceptor(),\n new BeaconInterceptor(),\n new ScriptInterceptor(),\n ];\n\n for (let i = 0; i < interceptors.length; i++) {\n try {\n interceptors[i].install(context);\n } catch (e) {\n if (options.debug) console.error(\"GA4 Duplicator: failed to install interceptor\", e);\n }\n }\n\n (window as any).__ga4DuplicatorInitialized = true;\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Package version identifier.\n * This value is replaced at build time via esbuild define.\n */\ndeclare const __D8A_VERSION__: string;\n\nfunction devVersionUtc(): string {\n const now = new Date();\n const year = String(now.getUTCFullYear()).slice(-2);\n const month = String(now.getUTCMonth() + 1).padStart(2, \"0\");\n return `dev-${year}-${month}`;\n}\n\nexport const version: string =\n typeof __D8A_VERSION__ !== \"undefined\" && __D8A_VERSION__ ? __D8A_VERSION__ : devVersionUtc();\n", "/**\n * GA4 Duplicator - Intercepts GA4 collect calls and sends duplicates to D8A.\n */\n\nimport { version } from \"./version\";\n\ninterface GA4Destination {\n measurement_id: string;\n server_container_url: string;\n convert_to_get?: boolean;\n}\n\ninterface GA4DuplicatorOptions {\n server_container_url?: string;\n destinations?: GA4Destination[];\n debug?: boolean;\n convert_to_get?: boolean;\n}\n\n(window as any).createGA4Duplicator = function (options: GA4DuplicatorOptions) {\n /**\n * Shared logic and configuration for interceptors.\n */\n interface InterceptorContext {\n debug: boolean;\n isTargetUrl(url: string | null | undefined): boolean;\n buildDuplicateUrl(url: string): string;\n getConvertToGet(url: string): boolean;\n }\n\n /**\n * Base interface for monkey-patching implementations.\n */\n interface NetworkInterceptor {\n install(context: InterceptorContext): void;\n }\n\n class FetchInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n const originalFetch = window.fetch;\n window.fetch = function (\n this: any,\n resource: RequestInfo | URL,\n config?: RequestInit,\n ): Promise<Response> {\n const requestUrl =\n typeof resource === \"string\"\n ? resource\n : resource instanceof URL\n ? resource.toString()\n : (resource as any).url;\n const method = (config && config.method) || (resource as any).method || \"GET\";\n\n if (ctx.isTargetUrl(requestUrl)) {\n const upperMethod = (method || \"GET\").toUpperCase();\n\n // If we need the body from a Request, clone BEFORE calling the original fetch\n let prepareBodyPromise: Promise<any> = Promise.resolve(undefined);\n if (upperMethod === \"POST\") {\n if (config && Object.prototype.hasOwnProperty.call(config, \"body\")) {\n prepareBodyPromise = Promise.resolve(config.body);\n } else if (typeof Request !== \"undefined\" && resource instanceof Request) {\n try {\n const clonedReq = resource.clone();\n prepareBodyPromise = clonedReq.blob().catch(() => undefined);\n } catch {\n prepareBodyPromise = Promise.resolve(undefined);\n }\n }\n }\n\n // First send original request to Google Analytics\n const originalPromise = originalFetch.apply(this, arguments as any);\n\n // Then send duplicate\n const duplicateUrl = ctx.buildDuplicateUrl(requestUrl);\n const convertToGet = ctx.getConvertToGet(requestUrl);\n\n if (upperMethod === \"GET\") {\n originalFetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating GET fetch:\", error);\n });\n } else if (upperMethod === \"POST\") {\n prepareBodyPromise.then((dupBody) => {\n if (convertToGet) {\n // Convert POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof dupBody === \"string\") {\n bodyStr = dupBody;\n } else if (dupBody instanceof Blob) {\n // For blob, we can't easily convert synchronously, so fall back to POST\n originalFetch(duplicateUrl, {\n method: \"POST\",\n body: dupBody,\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating POST fetch (convert_to_get with Blob):\",\n error,\n );\n });\n return;\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(requestUrl);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n originalFetch(urlWithMergedLine, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET fetch (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n originalFetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET fetch (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original POST duplication\n originalFetch(duplicateUrl, {\n method: \"POST\",\n body: dupBody,\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating POST fetch:\", error);\n });\n }\n });\n }\n\n return originalPromise;\n }\n\n return originalFetch.apply(this, arguments as any);\n };\n }\n }\n\n class XhrInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n const originalXHROpen = XMLHttpRequest.prototype.open;\n const originalXHRSend = XMLHttpRequest.prototype.send;\n\n XMLHttpRequest.prototype.open = function (this: any, method: string, url: string | URL) {\n this._requestMethod = method;\n this._requestUrl = url;\n return originalXHROpen.apply(this, arguments as any);\n };\n\n XMLHttpRequest.prototype.send = function (\n this: any,\n body?: Document | XMLHttpRequestBodyInit | null,\n ) {\n if (this._requestUrl && ctx.isTargetUrl(this._requestUrl)) {\n // First send original request to Google Analytics\n const originalResult = originalXHRSend.apply(this, arguments as any);\n\n // Then send duplicate to our endpoint mimicking method and payload\n try {\n const method = (this._requestMethod || \"GET\").toUpperCase();\n const duplicateUrl = ctx.buildDuplicateUrl(this._requestUrl);\n const convertToGet = ctx.getConvertToGet(this._requestUrl);\n\n if (method === \"GET\") {\n fetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating GET xhr:\", error);\n });\n } else if (method === \"POST\") {\n if (convertToGet) {\n // Convert POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof body === \"string\") {\n bodyStr = body;\n } else if (body && typeof body === \"object\") {\n // Try to convert Document or other types to string\n try {\n bodyStr = String(body);\n } catch {\n bodyStr = \"\";\n }\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(this._requestUrl);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n fetch(urlWithMergedLine, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET xhr (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n fetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET xhr (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original POST duplication\n fetch(duplicateUrl, {\n method: \"POST\",\n body: body as any,\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating POST xhr:\", error);\n });\n }\n }\n } catch (dupErr) {\n if (ctx.debug) console.error(\"gtm interceptor: xhr duplication failed:\", dupErr);\n }\n return originalResult;\n }\n return originalXHRSend.apply(this, arguments as any);\n };\n }\n }\n\n class BeaconInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n if (!navigator.sendBeacon) return;\n\n const originalSendBeacon = navigator.sendBeacon;\n navigator.sendBeacon = function (\n this: any,\n url: string | URL,\n data?: BodyInit | null,\n ): boolean {\n if (ctx.isTargetUrl(url as string)) {\n const originalResult = originalSendBeacon.apply(this, arguments as any);\n try {\n const duplicateUrl = ctx.buildDuplicateUrl(url as string);\n const convertToGet = ctx.getConvertToGet(url as string);\n\n if (convertToGet) {\n // Convert sendBeacon POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof data === \"string\") {\n bodyStr = data;\n } else if (data && typeof data === \"object\") {\n try {\n bodyStr = String(data);\n } catch {\n bodyStr = \"\";\n }\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(url as string);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n fetch(urlWithMergedLine, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET beacon (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n fetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET beacon (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original sendBeacon duplication\n originalSendBeacon.call(navigator, duplicateUrl, data);\n }\n } catch (e) {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating sendBeacon:\", e);\n }\n return originalResult;\n }\n return originalSendBeacon.apply(this, arguments as any);\n };\n }\n }\n\n class ScriptInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n try {\n const scriptSrcDescriptor = Object.getOwnPropertyDescriptor(\n HTMLScriptElement.prototype,\n \"src\",\n );\n const originalScriptSrcSetter = scriptSrcDescriptor && scriptSrcDescriptor.set;\n const originalScriptSrcGetter = scriptSrcDescriptor && scriptSrcDescriptor.get;\n const originalScriptSetAttribute = HTMLScriptElement.prototype.setAttribute;\n\n const duplicateIfGA4Url = (urlString: string) => {\n try {\n if (!ctx.isTargetUrl(urlString)) return;\n fetch(ctx.buildDuplicateUrl(urlString), {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating script GET:\", error);\n });\n } catch {\n // Intentionally empty\n }\n };\n\n if (originalScriptSrcSetter && originalScriptSrcGetter) {\n const setter = originalScriptSrcSetter;\n const getter = originalScriptSrcGetter;\n Object.defineProperty(HTMLScriptElement.prototype, \"src\", {\n configurable: true,\n enumerable: true,\n get: function (this: any) {\n return getter.call(this);\n },\n set: function (this: any, value: string) {\n try {\n const last = this.__ga4LastSrcDuplicated;\n if (value && value !== last) {\n duplicateIfGA4Url(String(value));\n this.__ga4LastSrcDuplicated = String(value);\n }\n const self = this;\n const onloadOnce = function () {\n try {\n const finalUrl = self.src;\n if (finalUrl && finalUrl !== self.__ga4LastSrcDuplicated) {\n duplicateIfGA4Url(finalUrl);\n self.__ga4LastSrcDuplicated = finalUrl;\n }\n } catch {}\n self.removeEventListener(\"load\", onloadOnce);\n };\n this.addEventListener(\"load\", onloadOnce);\n } catch {}\n setter.call(this, value);\n },\n });\n }\n\n HTMLScriptElement.prototype.setAttribute = function (\n this: any,\n name: string,\n value: string,\n ) {\n try {\n if (String(name).toLowerCase() === \"src\") {\n const v = String(value);\n const last = this.__ga4LastSrcDuplicated;\n if (v && v !== last) {\n duplicateIfGA4Url(v);\n this.__ga4LastSrcDuplicated = v;\n }\n const selfAttr = this;\n const onloadOnceAttr = function () {\n try {\n const finalUrlAttr = selfAttr.src;\n if (finalUrlAttr && finalUrlAttr !== selfAttr.__ga4LastSrcDuplicated) {\n duplicateIfGA4Url(finalUrlAttr);\n selfAttr.__ga4LastSrcDuplicated = finalUrlAttr;\n }\n } catch {}\n selfAttr.removeEventListener(\"load\", onloadOnceAttr);\n };\n this.addEventListener(\"load\", onloadOnceAttr);\n }\n } catch {\n // Intentionally empty\n }\n return originalScriptSetAttribute.apply(this, arguments as any);\n };\n } catch {}\n }\n }\n\n if ((window as any).__ga4DuplicatorInitialized) {\n if (options.debug) console.warn(\"GA4 Duplicator: already initialized.\");\n return;\n }\n\n const destinations: GA4Destination[] = [];\n if (options.destinations && Array.isArray(options.destinations)) {\n for (let i = 0; i < options.destinations.length; i++) {\n const dest = options.destinations[i];\n destinations.push({\n measurement_id: dest.measurement_id,\n server_container_url: dest.server_container_url,\n convert_to_get:\n dest.convert_to_get !== undefined ? dest.convert_to_get : options.convert_to_get,\n });\n }\n }\n\n if (options.server_container_url) {\n destinations.push({\n measurement_id: \"*\",\n server_container_url: options.server_container_url,\n convert_to_get: options.convert_to_get,\n });\n }\n\n if (destinations.length === 0) {\n console.error(\"GA4 Duplicator: either server_container_url or destinations array is required\");\n return;\n }\n\n function normalizePath(p: string): string {\n p = String(p || \"\");\n p = p.replace(/\\/+$/, \"\");\n return p === \"\" ? \"/\" : p;\n }\n\n function matchesId(pattern: string, id: string): boolean {\n if (!pattern || pattern === \"*\") return true;\n try {\n const regexStr = pattern.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\*/g, \".*\");\n return new RegExp(\"^\" + regexStr + \"$\", \"i\").test(id);\n } catch {\n return pattern.toLowerCase() === id.toLowerCase();\n }\n }\n\n function ensureBareQueryFlag(url: string, flag: string): string {\n const u = String(url || \"\");\n const f = String(flag || \"\").trim();\n if (!u || !f) return u;\n\n // Keep fragment intact\n const hashIdx = u.indexOf(\"#\");\n const beforeHash = hashIdx >= 0 ? u.slice(0, hashIdx) : u;\n const hash = hashIdx >= 0 ? u.slice(hashIdx) : \"\";\n\n const qIdx = beforeHash.indexOf(\"?\");\n const base = qIdx >= 0 ? beforeHash.slice(0, qIdx) : beforeHash;\n const rawQuery = qIdx >= 0 ? beforeHash.slice(qIdx + 1) : \"\";\n\n const parts = rawQuery\n ? rawQuery\n .split(\"&\")\n .map((p) => p.trim())\n .filter(Boolean)\n : [];\n\n const kept: string[] = [];\n for (let i = 0; i < parts.length; i++) {\n const p = parts[i];\n if (p === f) continue;\n if (p.startsWith(f + \"=\")) continue;\n kept.push(p);\n }\n\n const newQuery = kept.length > 0 ? kept.join(\"&\") + \"&\" + f : f;\n return base + \"?\" + newQuery + hash;\n }\n\n function getMeasurementId(url: string): string {\n try {\n const parsed = new URL(url, location.href);\n return parsed.searchParams.get(\"tid\") || parsed.searchParams.get(\"id\") || \"\";\n } catch {\n const match = url.match(/[?&](?:tid|id)=([^&?#]+)/);\n return match ? decodeURIComponent(match[1]) : \"\";\n }\n }\n\n function getDestinationForId(id: string): GA4Destination | null {\n for (let i = 0; i < destinations.length; i++) {\n if (matchesId(destinations[i].measurement_id, id)) {\n return destinations[i];\n }\n }\n return null;\n }\n\n function mergeBodyLineWithUrl(originalUrl: string, bodyLine: string): string {\n try {\n const url = new URL(originalUrl, location.href);\n const lineParams = new URLSearchParams(bodyLine);\n\n // Line parameters override URL parameters\n for (const [key] of lineParams.entries()) {\n url.searchParams.delete(key);\n }\n for (const [key, value] of lineParams.entries()) {\n url.searchParams.append(key, value);\n }\n\n return ensureBareQueryFlag(url.toString(), \"richsstsse\");\n } catch {\n // Fallback: if URL parsing fails, try string manipulation\n const urlWithoutQuery = originalUrl.split(\"?\")[0];\n const originalParams = originalUrl.match(/\\?(.*)/) ? originalUrl.match(/\\?(.*)/)![1] : \"\";\n const merged = originalParams + (originalParams && bodyLine ? \"&\" : \"\") + bodyLine;\n return ensureBareQueryFlag(urlWithoutQuery + (merged ? \"?\" + merged : \"\"), \"richsstsse\");\n }\n }\n\n function getDuplicateEndpointUrl(dest: GA4Destination): URL {\n const trackingURL = String(dest.server_container_url || \"\").trim();\n const u = new URL(trackingURL, location.href);\n u.search = \"\";\n u.hash = \"\";\n return u;\n }\n\n function isTargetUrl(url: string | null | undefined): boolean {\n if (!url || typeof url !== \"string\") return false;\n try {\n const parsed = new URL(url, location.href);\n\n for (let i = 0; i < destinations.length; i++) {\n const duplicateTarget = getDuplicateEndpointUrl(destinations[i]);\n if (\n parsed.origin === duplicateTarget.origin &&\n normalizePath(parsed.pathname) === normalizePath(duplicateTarget.pathname)\n ) {\n return false;\n }\n }\n\n const params = parsed.searchParams;\n const hasGtm = params.has(\"gtm\");\n const hasTagExp = params.has(\"tag_exp\");\n const measurementId = params.get(\"tid\") || params.get(\"id\") || \"\";\n const isMeasurementIdGA4 = /^G-[A-Z0-9]+$/i.test(measurementId);\n\n return hasGtm && hasTagExp && isMeasurementIdGA4;\n } catch {\n if (typeof url === \"string\") {\n for (let j = 0; j < destinations.length; j++) {\n try {\n const target = getDuplicateEndpointUrl(destinations[j]);\n const targetNoQuery = target.origin + target.pathname;\n if (url.indexOf(targetNoQuery) !== -1) return false;\n } catch {\n // Intentionally empty\n }\n }\n\n const hasGtmFallback = url.indexOf(\"gtm=\") !== -1;\n const hasTagExpFallback = url.indexOf(\"tag_exp=\") !== -1;\n const idMatch = url.match(/[?&](?:tid|id)=G-[A-Za-z0-9]+/);\n return !!(hasGtmFallback && hasTagExpFallback && idMatch);\n }\n return false;\n }\n }\n\n function buildDuplicateUrl(originalUrl: string): string {\n const id = getMeasurementId(originalUrl);\n const dest = getDestinationForId(id);\n if (!dest) return \"\";\n\n const dst = getDuplicateEndpointUrl(dest);\n try {\n const src = new URL(originalUrl, location.href);\n dst.search = src.search;\n dst.searchParams.set(\"_dtv\", version);\n dst.searchParams.set(\"_dtn\", \"gd\");\n } catch {}\n return ensureBareQueryFlag(dst.toString(), \"richsstsse\");\n }\n\n function getConvertToGet(url: string): boolean {\n const id = getMeasurementId(url);\n const dest = getDestinationForId(id);\n return dest ? !!dest.convert_to_get : false;\n }\n\n const context: InterceptorContext = {\n debug: !!options.debug,\n isTargetUrl,\n buildDuplicateUrl,\n getConvertToGet,\n };\n\n const interceptors: NetworkInterceptor[] = [\n new FetchInterceptor(),\n new XhrInterceptor(),\n new BeaconInterceptor(),\n new ScriptInterceptor(),\n ];\n\n for (let i = 0; i < interceptors.length; i++) {\n try {\n interceptors[i].install(context);\n } catch (e) {\n if (options.debug) console.error(\"GA4 Duplicator: failed to install interceptor\", e);\n }\n }\n\n (window as any).__ga4DuplicatorInitialized = true;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["e"]
|
|
7
7
|
}
|
package/dist/gd.min.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/* ga4-duplicator - built 2026-02-
|
|
2
|
-
"use strict";(()=>{var w="v0.
|
|
3
|
-
`),y=!1;for(let _=0;_<m.length;_++){let E=m[_].trim();if(E){let M=t.buildDuplicateUrl(o),H=b(M,E);e(H,{method:"GET",keepalive:!0}).catch(N=>{t.debug&&console.error("gtm interceptor: error duplicating GET fetch (from convert_to_get):",N)}),y=!0}}y||e(
|
|
4
|
-
`),u=!1;for(let c=0;c<
|
|
5
|
-
`),
|
|
1
|
+
/* ga4-duplicator - built 2026-02-20T20:15:46.018Z */
|
|
2
|
+
"use strict";(()=>{var w="v0.36.0";window.createGA4Duplicator=function(h){class L{install(t){let e=window.fetch;window.fetch=function(i,n){let o=typeof i=="string"?i:i instanceof URL?i.toString():i.url,g=n&&n.method||i.method||"GET";if(t.isTargetUrl(o)){let l=(g||"GET").toUpperCase(),d=Promise.resolve(void 0);if(l==="POST"){if(n&&Object.prototype.hasOwnProperty.call(n,"body"))d=Promise.resolve(n.body);else if(typeof Request!="undefined"&&i instanceof Request)try{d=i.clone().blob().catch(()=>{})}catch(c){d=Promise.resolve(void 0)}}let s=e.apply(this,arguments),p=t.buildDuplicateUrl(o),u=t.getConvertToGet(o);return l==="GET"?e(p,{method:"GET",keepalive:!0,credentials:"include"}).catch(c=>{t.debug&&console.error("gtm interceptor: error duplicating GET fetch:",c)}):l==="POST"&&d.then(c=>{if(u){let a="";if(typeof c=="string")a=c;else if(c instanceof Blob){e(p,{method:"POST",body:c,keepalive:!0,credentials:"include"}).catch(_=>{t.debug&&console.error("gtm interceptor: error duplicating POST fetch (convert_to_get with Blob):",_)});return}let m=a.split(`
|
|
3
|
+
`),y=!1;for(let _=0;_<m.length;_++){let E=m[_].trim();if(E){let M=t.buildDuplicateUrl(o),H=b(M,E);e(H,{method:"GET",keepalive:!0,credentials:"include"}).catch(N=>{t.debug&&console.error("gtm interceptor: error duplicating GET fetch (from convert_to_get):",N)}),y=!0}}y||e(p,{method:"GET",keepalive:!0,credentials:"include"}).catch(_=>{t.debug&&console.error("gtm interceptor: error duplicating GET fetch (empty body convert_to_get):",_)})}else e(p,{method:"POST",body:c,keepalive:!0,credentials:"include"}).catch(a=>{t.debug&&console.error("gtm interceptor: error duplicating POST fetch:",a)})}),s}return e.apply(this,arguments)}}}class I{install(t){let e=XMLHttpRequest.prototype.open,i=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(n,o){return this._requestMethod=n,this._requestUrl=o,e.apply(this,arguments)},XMLHttpRequest.prototype.send=function(n){if(this._requestUrl&&t.isTargetUrl(this._requestUrl)){let o=i.apply(this,arguments);try{let g=(this._requestMethod||"GET").toUpperCase(),l=t.buildDuplicateUrl(this._requestUrl),d=t.getConvertToGet(this._requestUrl);if(g==="GET")fetch(l,{method:"GET",keepalive:!0,credentials:"include"}).catch(s=>{t.debug&&console.error("gtm interceptor: error duplicating GET xhr:",s)});else if(g==="POST")if(d){let s="";if(typeof n=="string")s=n;else if(n&&typeof n=="object")try{s=String(n)}catch(c){s=""}let p=s.split(`
|
|
4
|
+
`),u=!1;for(let c=0;c<p.length;c++){let a=p[c].trim();if(a){let m=t.buildDuplicateUrl(this._requestUrl),y=b(m,a);fetch(y,{method:"GET",keepalive:!0,credentials:"include"}).catch(_=>{t.debug&&console.error("gtm interceptor: error duplicating GET xhr (from convert_to_get):",_)}),u=!0}}u||fetch(l,{method:"GET",keepalive:!0,credentials:"include"}).catch(c=>{t.debug&&console.error("gtm interceptor: error duplicating GET xhr (empty body convert_to_get):",c)})}else fetch(l,{method:"POST",body:n,keepalive:!0,credentials:"include"}).catch(s=>{t.debug&&console.error("gtm interceptor: error duplicating POST xhr:",s)})}catch(g){t.debug&&console.error("gtm interceptor: xhr duplication failed:",g)}return o}return i.apply(this,arguments)}}}class R{install(t){if(!navigator.sendBeacon)return;let e=navigator.sendBeacon;navigator.sendBeacon=function(i,n){if(t.isTargetUrl(i)){let o=e.apply(this,arguments);try{let g=t.buildDuplicateUrl(i);if(t.getConvertToGet(i)){let d="";if(typeof n=="string")d=n;else if(n&&typeof n=="object")try{d=String(n)}catch(u){d=""}let s=d.split(`
|
|
5
|
+
`),p=!1;for(let u=0;u<s.length;u++){let c=s[u].trim();if(c){let a=t.buildDuplicateUrl(i),m=b(a,c);fetch(m,{method:"GET",keepalive:!0,credentials:"include"}).catch(y=>{t.debug&&console.error("gtm interceptor: error duplicating GET beacon (from convert_to_get):",y)}),p=!0}}p||fetch(g,{method:"GET",keepalive:!0,credentials:"include"}).catch(u=>{t.debug&&console.error("gtm interceptor: error duplicating GET beacon (empty body convert_to_get):",u)})}else e.call(navigator,g,n)}catch(g){t.debug&&console.error("gtm interceptor: error duplicating sendBeacon:",g)}return o}return e.apply(this,arguments)}}}class A{install(t){try{let e=Object.getOwnPropertyDescriptor(HTMLScriptElement.prototype,"src"),i=e&&e.set,n=e&&e.get,o=HTMLScriptElement.prototype.setAttribute,g=l=>{try{if(!t.isTargetUrl(l))return;fetch(t.buildDuplicateUrl(l),{method:"GET",keepalive:!0,credentials:"include"}).catch(d=>{t.debug&&console.error("gtm interceptor: error duplicating script GET:",d)})}catch(d){}};if(i&&n){let l=i,d=n;Object.defineProperty(HTMLScriptElement.prototype,"src",{configurable:!0,enumerable:!0,get:function(){return d.call(this)},set:function(s){try{let p=this.__ga4LastSrcDuplicated;s&&s!==p&&(g(String(s)),this.__ga4LastSrcDuplicated=String(s));let u=this,c=function(){try{let a=u.src;a&&a!==u.__ga4LastSrcDuplicated&&(g(a),u.__ga4LastSrcDuplicated=a)}catch(a){}u.removeEventListener("load",c)};this.addEventListener("load",c)}catch(p){}l.call(this,s)}})}HTMLScriptElement.prototype.setAttribute=function(l,d){try{if(String(l).toLowerCase()==="src"){let s=String(d),p=this.__ga4LastSrcDuplicated;s&&s!==p&&(g(s),this.__ga4LastSrcDuplicated=s);let u=this,c=function(){try{let a=u.src;a&&a!==u.__ga4LastSrcDuplicated&&(g(a),u.__ga4LastSrcDuplicated=a)}catch(a){}u.removeEventListener("load",c)};this.addEventListener("load",c)}}catch(s){}return o.apply(this,arguments)}}catch(e){}}}if(window.__ga4DuplicatorInitialized){h.debug&&console.warn("GA4 Duplicator: already initialized.");return}let f=[];if(h.destinations&&Array.isArray(h.destinations))for(let r=0;r<h.destinations.length;r++){let t=h.destinations[r];f.push({measurement_id:t.measurement_id,server_container_url:t.server_container_url,convert_to_get:t.convert_to_get!==void 0?t.convert_to_get:h.convert_to_get})}if(h.server_container_url&&f.push({measurement_id:"*",server_container_url:h.server_container_url,convert_to_get:h.convert_to_get}),f.length===0){console.error("GA4 Duplicator: either server_container_url or destinations array is required");return}function T(r){return r=String(r||""),r=r.replace(/\/+$/,""),r===""?"/":r}function P(r,t){if(!r||r==="*")return!0;try{let e=r.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp("^"+e+"$","i").test(t)}catch(e){return r.toLowerCase()===t.toLowerCase()}}function v(r,t){let e=String(r||""),i=String(t||"").trim();if(!e||!i)return e;let n=e.indexOf("#"),o=n>=0?e.slice(0,n):e,g=n>=0?e.slice(n):"",l=o.indexOf("?"),d=l>=0?o.slice(0,l):o,s=l>=0?o.slice(l+1):"",p=s?s.split("&").map(a=>a.trim()).filter(Boolean):[],u=[];for(let a=0;a<p.length;a++){let m=p[a];m!==i&&(m.startsWith(i+"=")||u.push(m))}let c=u.length>0?u.join("&")+"&"+i:i;return d+"?"+c+g}function G(r){try{let t=new URL(r,location.href);return t.searchParams.get("tid")||t.searchParams.get("id")||""}catch(t){let e=r.match(/[?&](?:tid|id)=([^&?#]+)/);return e?decodeURIComponent(e[1]):""}}function U(r){for(let t=0;t<f.length;t++)if(P(f[t].measurement_id,r))return f[t];return null}function b(r,t){try{let e=new URL(r,location.href),i=new URLSearchParams(t);for(let[n]of i.entries())e.searchParams.delete(n);for(let[n,o]of i.entries())e.searchParams.append(n,o);return v(e.toString(),"richsstsse")}catch(e){let i=r.split("?")[0],n=r.match(/\?(.*)/)?r.match(/\?(.*)/)[1]:"",o=n+(n&&t?"&":"")+t;return v(i+(o?"?"+o:""),"richsstsse")}}function S(r){let t=String(r.server_container_url||"").trim(),e=new URL(t,location.href);return e.search="",e.hash="",e}function O(r){if(!r||typeof r!="string")return!1;try{let t=new URL(r,location.href);for(let l=0;l<f.length;l++){let d=S(f[l]);if(t.origin===d.origin&&T(t.pathname)===T(d.pathname))return!1}let e=t.searchParams,i=e.has("gtm"),n=e.has("tag_exp"),o=e.get("tid")||e.get("id")||"",g=/^G-[A-Z0-9]+$/i.test(o);return i&&n&&g}catch(t){if(typeof r=="string"){for(let o=0;o<f.length;o++)try{let g=S(f[o]),l=g.origin+g.pathname;if(r.indexOf(l)!==-1)return!1}catch(g){}let e=r.indexOf("gtm=")!==-1,i=r.indexOf("tag_exp=")!==-1,n=r.match(/[?&](?:tid|id)=G-[A-Za-z0-9]+/);return!!(e&&i&&n)}return!1}}function k(r){let t=G(r),e=U(t);if(!e)return"";let i=S(e);try{let n=new URL(r,location.href);i.search=n.search,i.searchParams.set("_dtv",w),i.searchParams.set("_dtn","gd")}catch(n){}return v(i.toString(),"richsstsse")}function q(r){let t=G(r),e=U(t);return e?!!e.convert_to_get:!1}let C={debug:!!h.debug,isTargetUrl:O,buildDuplicateUrl:k,getConvertToGet:q},D=[new L,new I,new R,new A];for(let r=0;r<D.length;r++)try{D[r].install(C)}catch(t){h.debug&&console.error("GA4 Duplicator: failed to install interceptor",t)}window.__ga4DuplicatorInitialized=!0};})();
|
|
6
6
|
//# sourceMappingURL=gd.min.js.map
|
package/dist/gd.min.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/version.ts", "../src/ga4-duplicator.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Package version identifier.\n * This value is replaced at build time via esbuild define.\n */\ndeclare const __D8A_VERSION__: string;\n\nfunction devVersionUtc(): string {\n const now = new Date();\n const year = String(now.getUTCFullYear()).slice(-2);\n const month = String(now.getUTCMonth() + 1).padStart(2, \"0\");\n return `dev-${year}-${month}`;\n}\n\nexport const version: string =\n typeof __D8A_VERSION__ !== \"undefined\" && __D8A_VERSION__ ? __D8A_VERSION__ : devVersionUtc();\n", "/**\n * GA4 Duplicator - Intercepts GA4 collect calls and sends duplicates to D8A.\n */\n\nimport { version } from \"./version\";\n\ninterface GA4Destination {\n measurement_id: string;\n server_container_url: string;\n convert_to_get?: boolean;\n}\n\ninterface GA4DuplicatorOptions {\n server_container_url?: string;\n destinations?: GA4Destination[];\n debug?: boolean;\n convert_to_get?: boolean;\n}\n\n(window as any).createGA4Duplicator = function (options: GA4DuplicatorOptions) {\n /**\n * Shared logic and configuration for interceptors.\n */\n interface InterceptorContext {\n debug: boolean;\n isTargetUrl(url: string | null | undefined): boolean;\n buildDuplicateUrl(url: string): string;\n getConvertToGet(url: string): boolean;\n }\n\n /**\n * Base interface for monkey-patching implementations.\n */\n interface NetworkInterceptor {\n install(context: InterceptorContext): void;\n }\n\n class FetchInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n const originalFetch = window.fetch;\n window.fetch = function (\n this: any,\n resource: RequestInfo | URL,\n config?: RequestInit,\n ): Promise<Response> {\n const requestUrl =\n typeof resource === \"string\"\n ? resource\n : resource instanceof URL\n ? resource.toString()\n : (resource as any).url;\n const method = (config && config.method) || (resource as any).method || \"GET\";\n\n if (ctx.isTargetUrl(requestUrl)) {\n const upperMethod = (method || \"GET\").toUpperCase();\n\n // If we need the body from a Request, clone BEFORE calling the original fetch\n let prepareBodyPromise: Promise<any> = Promise.resolve(undefined);\n if (upperMethod === \"POST\") {\n if (config && Object.prototype.hasOwnProperty.call(config, \"body\")) {\n prepareBodyPromise = Promise.resolve(config.body);\n } else if (typeof Request !== \"undefined\" && resource instanceof Request) {\n try {\n const clonedReq = resource.clone();\n prepareBodyPromise = clonedReq.blob().catch(() => undefined);\n } catch {\n prepareBodyPromise = Promise.resolve(undefined);\n }\n }\n }\n\n // First send original request to Google Analytics\n const originalPromise = originalFetch.apply(this, arguments as any);\n\n // Then send duplicate\n const duplicateUrl = ctx.buildDuplicateUrl(requestUrl);\n const convertToGet = ctx.getConvertToGet(requestUrl);\n\n if (upperMethod === \"GET\") {\n originalFetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating GET fetch:\", error);\n });\n } else if (upperMethod === \"POST\") {\n prepareBodyPromise.then((dupBody) => {\n if (convertToGet) {\n // Convert POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof dupBody === \"string\") {\n bodyStr = dupBody;\n } else if (dupBody instanceof Blob) {\n // For blob, we can't easily convert synchronously, so fall back to POST\n originalFetch(duplicateUrl, {\n method: \"POST\",\n body: dupBody,\n keepalive: true,\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating POST fetch (convert_to_get with Blob):\",\n error,\n );\n });\n return;\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(requestUrl);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n originalFetch(urlWithMergedLine, { method: \"GET\", keepalive: true }).catch(\n (error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET fetch (from convert_to_get):\",\n error,\n );\n },\n );\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n originalFetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET fetch (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original POST duplication\n originalFetch(duplicateUrl, {\n method: \"POST\",\n body: dupBody,\n keepalive: true,\n }).catch((error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating POST fetch:\", error);\n });\n }\n });\n }\n\n return originalPromise;\n }\n\n return originalFetch.apply(this, arguments as any);\n };\n }\n }\n\n class XhrInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n const originalXHROpen = XMLHttpRequest.prototype.open;\n const originalXHRSend = XMLHttpRequest.prototype.send;\n\n XMLHttpRequest.prototype.open = function (this: any, method: string, url: string | URL) {\n this._requestMethod = method;\n this._requestUrl = url;\n return originalXHROpen.apply(this, arguments as any);\n };\n\n XMLHttpRequest.prototype.send = function (\n this: any,\n body?: Document | XMLHttpRequestBodyInit | null,\n ) {\n if (this._requestUrl && ctx.isTargetUrl(this._requestUrl)) {\n // First send original request to Google Analytics\n const originalResult = originalXHRSend.apply(this, arguments as any);\n\n // Then send duplicate to our endpoint mimicking method and payload\n try {\n const method = (this._requestMethod || \"GET\").toUpperCase();\n const duplicateUrl = ctx.buildDuplicateUrl(this._requestUrl);\n const convertToGet = ctx.getConvertToGet(this._requestUrl);\n\n if (method === \"GET\") {\n fetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating GET xhr:\", error);\n });\n } else if (method === \"POST\") {\n if (convertToGet) {\n // Convert POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof body === \"string\") {\n bodyStr = body;\n } else if (body && typeof body === \"object\") {\n // Try to convert Document or other types to string\n try {\n bodyStr = String(body);\n } catch {\n bodyStr = \"\";\n }\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(this._requestUrl);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n fetch(urlWithMergedLine, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET xhr (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n fetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET xhr (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original POST duplication\n fetch(duplicateUrl, { method: \"POST\", body: body as any, keepalive: true }).catch(\n (error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating POST xhr:\", error);\n },\n );\n }\n }\n } catch (dupErr) {\n if (ctx.debug) console.error(\"gtm interceptor: xhr duplication failed:\", dupErr);\n }\n return originalResult;\n }\n return originalXHRSend.apply(this, arguments as any);\n };\n }\n }\n\n class BeaconInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n if (!navigator.sendBeacon) return;\n\n const originalSendBeacon = navigator.sendBeacon;\n navigator.sendBeacon = function (\n this: any,\n url: string | URL,\n data?: BodyInit | null,\n ): boolean {\n if (ctx.isTargetUrl(url as string)) {\n const originalResult = originalSendBeacon.apply(this, arguments as any);\n try {\n const duplicateUrl = ctx.buildDuplicateUrl(url as string);\n const convertToGet = ctx.getConvertToGet(url as string);\n\n if (convertToGet) {\n // Convert sendBeacon POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof data === \"string\") {\n bodyStr = data;\n } else if (data && typeof data === \"object\") {\n try {\n bodyStr = String(data);\n } catch {\n bodyStr = \"\";\n }\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(url as string);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n fetch(urlWithMergedLine, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET beacon (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n fetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET beacon (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original sendBeacon duplication\n originalSendBeacon.call(navigator, duplicateUrl, data);\n }\n } catch (e) {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating sendBeacon:\", e);\n }\n return originalResult;\n }\n return originalSendBeacon.apply(this, arguments as any);\n };\n }\n }\n\n class ScriptInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n try {\n const scriptSrcDescriptor = Object.getOwnPropertyDescriptor(\n HTMLScriptElement.prototype,\n \"src\",\n );\n const originalScriptSrcSetter = scriptSrcDescriptor && scriptSrcDescriptor.set;\n const originalScriptSrcGetter = scriptSrcDescriptor && scriptSrcDescriptor.get;\n const originalScriptSetAttribute = HTMLScriptElement.prototype.setAttribute;\n\n const duplicateIfGA4Url = (urlString: string) => {\n try {\n if (!ctx.isTargetUrl(urlString)) return;\n fetch(ctx.buildDuplicateUrl(urlString), { method: \"GET\", keepalive: true }).catch(\n (error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating script GET:\", error);\n },\n );\n } catch {\n // Intentionally empty\n }\n };\n\n if (originalScriptSrcSetter && originalScriptSrcGetter) {\n const setter = originalScriptSrcSetter;\n const getter = originalScriptSrcGetter;\n Object.defineProperty(HTMLScriptElement.prototype, \"src\", {\n configurable: true,\n enumerable: true,\n get: function (this: any) {\n return getter.call(this);\n },\n set: function (this: any, value: string) {\n try {\n const last = this.__ga4LastSrcDuplicated;\n if (value && value !== last) {\n duplicateIfGA4Url(String(value));\n this.__ga4LastSrcDuplicated = String(value);\n }\n const self = this;\n const onloadOnce = function () {\n try {\n const finalUrl = self.src;\n if (finalUrl && finalUrl !== self.__ga4LastSrcDuplicated) {\n duplicateIfGA4Url(finalUrl);\n self.__ga4LastSrcDuplicated = finalUrl;\n }\n } catch {}\n self.removeEventListener(\"load\", onloadOnce);\n };\n this.addEventListener(\"load\", onloadOnce);\n } catch {}\n setter.call(this, value);\n },\n });\n }\n\n HTMLScriptElement.prototype.setAttribute = function (\n this: any,\n name: string,\n value: string,\n ) {\n try {\n if (String(name).toLowerCase() === \"src\") {\n const v = String(value);\n const last = this.__ga4LastSrcDuplicated;\n if (v && v !== last) {\n duplicateIfGA4Url(v);\n this.__ga4LastSrcDuplicated = v;\n }\n const selfAttr = this;\n const onloadOnceAttr = function () {\n try {\n const finalUrlAttr = selfAttr.src;\n if (finalUrlAttr && finalUrlAttr !== selfAttr.__ga4LastSrcDuplicated) {\n duplicateIfGA4Url(finalUrlAttr);\n selfAttr.__ga4LastSrcDuplicated = finalUrlAttr;\n }\n } catch {}\n selfAttr.removeEventListener(\"load\", onloadOnceAttr);\n };\n this.addEventListener(\"load\", onloadOnceAttr);\n }\n } catch {\n // Intentionally empty\n }\n return originalScriptSetAttribute.apply(this, arguments as any);\n };\n } catch {}\n }\n }\n\n if ((window as any).__ga4DuplicatorInitialized) {\n if (options.debug) console.warn(\"GA4 Duplicator: already initialized.\");\n return;\n }\n\n const destinations: GA4Destination[] = [];\n if (options.destinations && Array.isArray(options.destinations)) {\n for (let i = 0; i < options.destinations.length; i++) {\n const dest = options.destinations[i];\n destinations.push({\n measurement_id: dest.measurement_id,\n server_container_url: dest.server_container_url,\n convert_to_get:\n dest.convert_to_get !== undefined ? dest.convert_to_get : options.convert_to_get,\n });\n }\n }\n\n if (options.server_container_url) {\n destinations.push({\n measurement_id: \"*\",\n server_container_url: options.server_container_url,\n convert_to_get: options.convert_to_get,\n });\n }\n\n if (destinations.length === 0) {\n console.error(\"GA4 Duplicator: either server_container_url or destinations array is required\");\n return;\n }\n\n function normalizePath(p: string): string {\n p = String(p || \"\");\n p = p.replace(/\\/+$/, \"\");\n return p === \"\" ? \"/\" : p;\n }\n\n function matchesId(pattern: string, id: string): boolean {\n if (!pattern || pattern === \"*\") return true;\n try {\n const regexStr = pattern.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\*/g, \".*\");\n return new RegExp(\"^\" + regexStr + \"$\", \"i\").test(id);\n } catch {\n return pattern.toLowerCase() === id.toLowerCase();\n }\n }\n\n function ensureBareQueryFlag(url: string, flag: string): string {\n const u = String(url || \"\");\n const f = String(flag || \"\").trim();\n if (!u || !f) return u;\n\n // Keep fragment intact\n const hashIdx = u.indexOf(\"#\");\n const beforeHash = hashIdx >= 0 ? u.slice(0, hashIdx) : u;\n const hash = hashIdx >= 0 ? u.slice(hashIdx) : \"\";\n\n const qIdx = beforeHash.indexOf(\"?\");\n const base = qIdx >= 0 ? beforeHash.slice(0, qIdx) : beforeHash;\n const rawQuery = qIdx >= 0 ? beforeHash.slice(qIdx + 1) : \"\";\n\n const parts = rawQuery\n ? rawQuery\n .split(\"&\")\n .map((p) => p.trim())\n .filter(Boolean)\n : [];\n\n const kept: string[] = [];\n for (let i = 0; i < parts.length; i++) {\n const p = parts[i];\n if (p === f) continue;\n if (p.startsWith(f + \"=\")) continue;\n kept.push(p);\n }\n\n const newQuery = kept.length > 0 ? kept.join(\"&\") + \"&\" + f : f;\n return base + \"?\" + newQuery + hash;\n }\n\n function getMeasurementId(url: string): string {\n try {\n const parsed = new URL(url, location.href);\n return parsed.searchParams.get(\"tid\") || parsed.searchParams.get(\"id\") || \"\";\n } catch {\n const match = url.match(/[?&](?:tid|id)=([^&?#]+)/);\n return match ? decodeURIComponent(match[1]) : \"\";\n }\n }\n\n function getDestinationForId(id: string): GA4Destination | null {\n for (let i = 0; i < destinations.length; i++) {\n if (matchesId(destinations[i].measurement_id, id)) {\n return destinations[i];\n }\n }\n return null;\n }\n\n function mergeBodyLineWithUrl(originalUrl: string, bodyLine: string): string {\n try {\n const url = new URL(originalUrl, location.href);\n const lineParams = new URLSearchParams(bodyLine);\n\n // Line parameters override URL parameters\n for (const [key] of lineParams.entries()) {\n url.searchParams.delete(key);\n }\n for (const [key, value] of lineParams.entries()) {\n url.searchParams.append(key, value);\n }\n\n return ensureBareQueryFlag(url.toString(), \"richsstsse\");\n } catch {\n // Fallback: if URL parsing fails, try string manipulation\n const urlWithoutQuery = originalUrl.split(\"?\")[0];\n const originalParams = originalUrl.match(/\\?(.*)/) ? originalUrl.match(/\\?(.*)/)![1] : \"\";\n const merged = originalParams + (originalParams && bodyLine ? \"&\" : \"\") + bodyLine;\n return ensureBareQueryFlag(urlWithoutQuery + (merged ? \"?\" + merged : \"\"), \"richsstsse\");\n }\n }\n\n function getDuplicateEndpointUrl(dest: GA4Destination): URL {\n const trackingURL = String(dest.server_container_url || \"\").trim();\n const u = new URL(trackingURL, location.href);\n u.search = \"\";\n u.hash = \"\";\n return u;\n }\n\n function isTargetUrl(url: string | null | undefined): boolean {\n if (!url || typeof url !== \"string\") return false;\n try {\n const parsed = new URL(url, location.href);\n\n for (let i = 0; i < destinations.length; i++) {\n const duplicateTarget = getDuplicateEndpointUrl(destinations[i]);\n if (\n parsed.origin === duplicateTarget.origin &&\n normalizePath(parsed.pathname) === normalizePath(duplicateTarget.pathname)\n ) {\n return false;\n }\n }\n\n const params = parsed.searchParams;\n const hasGtm = params.has(\"gtm\");\n const hasTagExp = params.has(\"tag_exp\");\n const measurementId = params.get(\"tid\") || params.get(\"id\") || \"\";\n const isMeasurementIdGA4 = /^G-[A-Z0-9]+$/i.test(measurementId);\n\n return hasGtm && hasTagExp && isMeasurementIdGA4;\n } catch {\n if (typeof url === \"string\") {\n for (let j = 0; j < destinations.length; j++) {\n try {\n const target = getDuplicateEndpointUrl(destinations[j]);\n const targetNoQuery = target.origin + target.pathname;\n if (url.indexOf(targetNoQuery) !== -1) return false;\n } catch {\n // Intentionally empty\n }\n }\n\n const hasGtmFallback = url.indexOf(\"gtm=\") !== -1;\n const hasTagExpFallback = url.indexOf(\"tag_exp=\") !== -1;\n const idMatch = url.match(/[?&](?:tid|id)=G-[A-Za-z0-9]+/);\n return !!(hasGtmFallback && hasTagExpFallback && idMatch);\n }\n return false;\n }\n }\n\n function buildDuplicateUrl(originalUrl: string): string {\n const id = getMeasurementId(originalUrl);\n const dest = getDestinationForId(id);\n if (!dest) return \"\";\n\n const dst = getDuplicateEndpointUrl(dest);\n try {\n const src = new URL(originalUrl, location.href);\n dst.search = src.search;\n dst.searchParams.set(\"_dtv\", version);\n dst.searchParams.set(\"_dtn\", \"gd\");\n } catch {}\n return ensureBareQueryFlag(dst.toString(), \"richsstsse\");\n }\n\n function getConvertToGet(url: string): boolean {\n const id = getMeasurementId(url);\n const dest = getDestinationForId(id);\n return dest ? !!dest.convert_to_get : false;\n }\n\n const context: InterceptorContext = {\n debug: !!options.debug,\n isTargetUrl,\n buildDuplicateUrl,\n getConvertToGet,\n };\n\n const interceptors: NetworkInterceptor[] = [\n new FetchInterceptor(),\n new XhrInterceptor(),\n new BeaconInterceptor(),\n new ScriptInterceptor(),\n ];\n\n for (let i = 0; i < interceptors.length; i++) {\n try {\n interceptors[i].install(context);\n } catch (e) {\n if (options.debug) console.error(\"GA4 Duplicator: failed to install interceptor\", e);\n }\n }\n\n (window as any).__ga4DuplicatorInitialized = true;\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Package version identifier.\n * This value is replaced at build time via esbuild define.\n */\ndeclare const __D8A_VERSION__: string;\n\nfunction devVersionUtc(): string {\n const now = new Date();\n const year = String(now.getUTCFullYear()).slice(-2);\n const month = String(now.getUTCMonth() + 1).padStart(2, \"0\");\n return `dev-${year}-${month}`;\n}\n\nexport const version: string =\n typeof __D8A_VERSION__ !== \"undefined\" && __D8A_VERSION__ ? __D8A_VERSION__ : devVersionUtc();\n", "/**\n * GA4 Duplicator - Intercepts GA4 collect calls and sends duplicates to D8A.\n */\n\nimport { version } from \"./version\";\n\ninterface GA4Destination {\n measurement_id: string;\n server_container_url: string;\n convert_to_get?: boolean;\n}\n\ninterface GA4DuplicatorOptions {\n server_container_url?: string;\n destinations?: GA4Destination[];\n debug?: boolean;\n convert_to_get?: boolean;\n}\n\n(window as any).createGA4Duplicator = function (options: GA4DuplicatorOptions) {\n /**\n * Shared logic and configuration for interceptors.\n */\n interface InterceptorContext {\n debug: boolean;\n isTargetUrl(url: string | null | undefined): boolean;\n buildDuplicateUrl(url: string): string;\n getConvertToGet(url: string): boolean;\n }\n\n /**\n * Base interface for monkey-patching implementations.\n */\n interface NetworkInterceptor {\n install(context: InterceptorContext): void;\n }\n\n class FetchInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n const originalFetch = window.fetch;\n window.fetch = function (\n this: any,\n resource: RequestInfo | URL,\n config?: RequestInit,\n ): Promise<Response> {\n const requestUrl =\n typeof resource === \"string\"\n ? resource\n : resource instanceof URL\n ? resource.toString()\n : (resource as any).url;\n const method = (config && config.method) || (resource as any).method || \"GET\";\n\n if (ctx.isTargetUrl(requestUrl)) {\n const upperMethod = (method || \"GET\").toUpperCase();\n\n // If we need the body from a Request, clone BEFORE calling the original fetch\n let prepareBodyPromise: Promise<any> = Promise.resolve(undefined);\n if (upperMethod === \"POST\") {\n if (config && Object.prototype.hasOwnProperty.call(config, \"body\")) {\n prepareBodyPromise = Promise.resolve(config.body);\n } else if (typeof Request !== \"undefined\" && resource instanceof Request) {\n try {\n const clonedReq = resource.clone();\n prepareBodyPromise = clonedReq.blob().catch(() => undefined);\n } catch {\n prepareBodyPromise = Promise.resolve(undefined);\n }\n }\n }\n\n // First send original request to Google Analytics\n const originalPromise = originalFetch.apply(this, arguments as any);\n\n // Then send duplicate\n const duplicateUrl = ctx.buildDuplicateUrl(requestUrl);\n const convertToGet = ctx.getConvertToGet(requestUrl);\n\n if (upperMethod === \"GET\") {\n originalFetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating GET fetch:\", error);\n });\n } else if (upperMethod === \"POST\") {\n prepareBodyPromise.then((dupBody) => {\n if (convertToGet) {\n // Convert POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof dupBody === \"string\") {\n bodyStr = dupBody;\n } else if (dupBody instanceof Blob) {\n // For blob, we can't easily convert synchronously, so fall back to POST\n originalFetch(duplicateUrl, {\n method: \"POST\",\n body: dupBody,\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating POST fetch (convert_to_get with Blob):\",\n error,\n );\n });\n return;\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(requestUrl);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n originalFetch(urlWithMergedLine, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET fetch (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n originalFetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET fetch (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original POST duplication\n originalFetch(duplicateUrl, {\n method: \"POST\",\n body: dupBody,\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating POST fetch:\", error);\n });\n }\n });\n }\n\n return originalPromise;\n }\n\n return originalFetch.apply(this, arguments as any);\n };\n }\n }\n\n class XhrInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n const originalXHROpen = XMLHttpRequest.prototype.open;\n const originalXHRSend = XMLHttpRequest.prototype.send;\n\n XMLHttpRequest.prototype.open = function (this: any, method: string, url: string | URL) {\n this._requestMethod = method;\n this._requestUrl = url;\n return originalXHROpen.apply(this, arguments as any);\n };\n\n XMLHttpRequest.prototype.send = function (\n this: any,\n body?: Document | XMLHttpRequestBodyInit | null,\n ) {\n if (this._requestUrl && ctx.isTargetUrl(this._requestUrl)) {\n // First send original request to Google Analytics\n const originalResult = originalXHRSend.apply(this, arguments as any);\n\n // Then send duplicate to our endpoint mimicking method and payload\n try {\n const method = (this._requestMethod || \"GET\").toUpperCase();\n const duplicateUrl = ctx.buildDuplicateUrl(this._requestUrl);\n const convertToGet = ctx.getConvertToGet(this._requestUrl);\n\n if (method === \"GET\") {\n fetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating GET xhr:\", error);\n });\n } else if (method === \"POST\") {\n if (convertToGet) {\n // Convert POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof body === \"string\") {\n bodyStr = body;\n } else if (body && typeof body === \"object\") {\n // Try to convert Document or other types to string\n try {\n bodyStr = String(body);\n } catch {\n bodyStr = \"\";\n }\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(this._requestUrl);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n fetch(urlWithMergedLine, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET xhr (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n fetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET xhr (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original POST duplication\n fetch(duplicateUrl, {\n method: \"POST\",\n body: body as any,\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating POST xhr:\", error);\n });\n }\n }\n } catch (dupErr) {\n if (ctx.debug) console.error(\"gtm interceptor: xhr duplication failed:\", dupErr);\n }\n return originalResult;\n }\n return originalXHRSend.apply(this, arguments as any);\n };\n }\n }\n\n class BeaconInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n if (!navigator.sendBeacon) return;\n\n const originalSendBeacon = navigator.sendBeacon;\n navigator.sendBeacon = function (\n this: any,\n url: string | URL,\n data?: BodyInit | null,\n ): boolean {\n if (ctx.isTargetUrl(url as string)) {\n const originalResult = originalSendBeacon.apply(this, arguments as any);\n try {\n const duplicateUrl = ctx.buildDuplicateUrl(url as string);\n const convertToGet = ctx.getConvertToGet(url as string);\n\n if (convertToGet) {\n // Convert sendBeacon POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof data === \"string\") {\n bodyStr = data;\n } else if (data && typeof data === \"object\") {\n try {\n bodyStr = String(data);\n } catch {\n bodyStr = \"\";\n }\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(url as string);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n fetch(urlWithMergedLine, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET beacon (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n fetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET beacon (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original sendBeacon duplication\n originalSendBeacon.call(navigator, duplicateUrl, data);\n }\n } catch (e) {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating sendBeacon:\", e);\n }\n return originalResult;\n }\n return originalSendBeacon.apply(this, arguments as any);\n };\n }\n }\n\n class ScriptInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n try {\n const scriptSrcDescriptor = Object.getOwnPropertyDescriptor(\n HTMLScriptElement.prototype,\n \"src\",\n );\n const originalScriptSrcSetter = scriptSrcDescriptor && scriptSrcDescriptor.set;\n const originalScriptSrcGetter = scriptSrcDescriptor && scriptSrcDescriptor.get;\n const originalScriptSetAttribute = HTMLScriptElement.prototype.setAttribute;\n\n const duplicateIfGA4Url = (urlString: string) => {\n try {\n if (!ctx.isTargetUrl(urlString)) return;\n fetch(ctx.buildDuplicateUrl(urlString), {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating script GET:\", error);\n });\n } catch {\n // Intentionally empty\n }\n };\n\n if (originalScriptSrcSetter && originalScriptSrcGetter) {\n const setter = originalScriptSrcSetter;\n const getter = originalScriptSrcGetter;\n Object.defineProperty(HTMLScriptElement.prototype, \"src\", {\n configurable: true,\n enumerable: true,\n get: function (this: any) {\n return getter.call(this);\n },\n set: function (this: any, value: string) {\n try {\n const last = this.__ga4LastSrcDuplicated;\n if (value && value !== last) {\n duplicateIfGA4Url(String(value));\n this.__ga4LastSrcDuplicated = String(value);\n }\n const self = this;\n const onloadOnce = function () {\n try {\n const finalUrl = self.src;\n if (finalUrl && finalUrl !== self.__ga4LastSrcDuplicated) {\n duplicateIfGA4Url(finalUrl);\n self.__ga4LastSrcDuplicated = finalUrl;\n }\n } catch {}\n self.removeEventListener(\"load\", onloadOnce);\n };\n this.addEventListener(\"load\", onloadOnce);\n } catch {}\n setter.call(this, value);\n },\n });\n }\n\n HTMLScriptElement.prototype.setAttribute = function (\n this: any,\n name: string,\n value: string,\n ) {\n try {\n if (String(name).toLowerCase() === \"src\") {\n const v = String(value);\n const last = this.__ga4LastSrcDuplicated;\n if (v && v !== last) {\n duplicateIfGA4Url(v);\n this.__ga4LastSrcDuplicated = v;\n }\n const selfAttr = this;\n const onloadOnceAttr = function () {\n try {\n const finalUrlAttr = selfAttr.src;\n if (finalUrlAttr && finalUrlAttr !== selfAttr.__ga4LastSrcDuplicated) {\n duplicateIfGA4Url(finalUrlAttr);\n selfAttr.__ga4LastSrcDuplicated = finalUrlAttr;\n }\n } catch {}\n selfAttr.removeEventListener(\"load\", onloadOnceAttr);\n };\n this.addEventListener(\"load\", onloadOnceAttr);\n }\n } catch {\n // Intentionally empty\n }\n return originalScriptSetAttribute.apply(this, arguments as any);\n };\n } catch {}\n }\n }\n\n if ((window as any).__ga4DuplicatorInitialized) {\n if (options.debug) console.warn(\"GA4 Duplicator: already initialized.\");\n return;\n }\n\n const destinations: GA4Destination[] = [];\n if (options.destinations && Array.isArray(options.destinations)) {\n for (let i = 0; i < options.destinations.length; i++) {\n const dest = options.destinations[i];\n destinations.push({\n measurement_id: dest.measurement_id,\n server_container_url: dest.server_container_url,\n convert_to_get:\n dest.convert_to_get !== undefined ? dest.convert_to_get : options.convert_to_get,\n });\n }\n }\n\n if (options.server_container_url) {\n destinations.push({\n measurement_id: \"*\",\n server_container_url: options.server_container_url,\n convert_to_get: options.convert_to_get,\n });\n }\n\n if (destinations.length === 0) {\n console.error(\"GA4 Duplicator: either server_container_url or destinations array is required\");\n return;\n }\n\n function normalizePath(p: string): string {\n p = String(p || \"\");\n p = p.replace(/\\/+$/, \"\");\n return p === \"\" ? \"/\" : p;\n }\n\n function matchesId(pattern: string, id: string): boolean {\n if (!pattern || pattern === \"*\") return true;\n try {\n const regexStr = pattern.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\*/g, \".*\");\n return new RegExp(\"^\" + regexStr + \"$\", \"i\").test(id);\n } catch {\n return pattern.toLowerCase() === id.toLowerCase();\n }\n }\n\n function ensureBareQueryFlag(url: string, flag: string): string {\n const u = String(url || \"\");\n const f = String(flag || \"\").trim();\n if (!u || !f) return u;\n\n // Keep fragment intact\n const hashIdx = u.indexOf(\"#\");\n const beforeHash = hashIdx >= 0 ? u.slice(0, hashIdx) : u;\n const hash = hashIdx >= 0 ? u.slice(hashIdx) : \"\";\n\n const qIdx = beforeHash.indexOf(\"?\");\n const base = qIdx >= 0 ? beforeHash.slice(0, qIdx) : beforeHash;\n const rawQuery = qIdx >= 0 ? beforeHash.slice(qIdx + 1) : \"\";\n\n const parts = rawQuery\n ? rawQuery\n .split(\"&\")\n .map((p) => p.trim())\n .filter(Boolean)\n : [];\n\n const kept: string[] = [];\n for (let i = 0; i < parts.length; i++) {\n const p = parts[i];\n if (p === f) continue;\n if (p.startsWith(f + \"=\")) continue;\n kept.push(p);\n }\n\n const newQuery = kept.length > 0 ? kept.join(\"&\") + \"&\" + f : f;\n return base + \"?\" + newQuery + hash;\n }\n\n function getMeasurementId(url: string): string {\n try {\n const parsed = new URL(url, location.href);\n return parsed.searchParams.get(\"tid\") || parsed.searchParams.get(\"id\") || \"\";\n } catch {\n const match = url.match(/[?&](?:tid|id)=([^&?#]+)/);\n return match ? decodeURIComponent(match[1]) : \"\";\n }\n }\n\n function getDestinationForId(id: string): GA4Destination | null {\n for (let i = 0; i < destinations.length; i++) {\n if (matchesId(destinations[i].measurement_id, id)) {\n return destinations[i];\n }\n }\n return null;\n }\n\n function mergeBodyLineWithUrl(originalUrl: string, bodyLine: string): string {\n try {\n const url = new URL(originalUrl, location.href);\n const lineParams = new URLSearchParams(bodyLine);\n\n // Line parameters override URL parameters\n for (const [key] of lineParams.entries()) {\n url.searchParams.delete(key);\n }\n for (const [key, value] of lineParams.entries()) {\n url.searchParams.append(key, value);\n }\n\n return ensureBareQueryFlag(url.toString(), \"richsstsse\");\n } catch {\n // Fallback: if URL parsing fails, try string manipulation\n const urlWithoutQuery = originalUrl.split(\"?\")[0];\n const originalParams = originalUrl.match(/\\?(.*)/) ? originalUrl.match(/\\?(.*)/)![1] : \"\";\n const merged = originalParams + (originalParams && bodyLine ? \"&\" : \"\") + bodyLine;\n return ensureBareQueryFlag(urlWithoutQuery + (merged ? \"?\" + merged : \"\"), \"richsstsse\");\n }\n }\n\n function getDuplicateEndpointUrl(dest: GA4Destination): URL {\n const trackingURL = String(dest.server_container_url || \"\").trim();\n const u = new URL(trackingURL, location.href);\n u.search = \"\";\n u.hash = \"\";\n return u;\n }\n\n function isTargetUrl(url: string | null | undefined): boolean {\n if (!url || typeof url !== \"string\") return false;\n try {\n const parsed = new URL(url, location.href);\n\n for (let i = 0; i < destinations.length; i++) {\n const duplicateTarget = getDuplicateEndpointUrl(destinations[i]);\n if (\n parsed.origin === duplicateTarget.origin &&\n normalizePath(parsed.pathname) === normalizePath(duplicateTarget.pathname)\n ) {\n return false;\n }\n }\n\n const params = parsed.searchParams;\n const hasGtm = params.has(\"gtm\");\n const hasTagExp = params.has(\"tag_exp\");\n const measurementId = params.get(\"tid\") || params.get(\"id\") || \"\";\n const isMeasurementIdGA4 = /^G-[A-Z0-9]+$/i.test(measurementId);\n\n return hasGtm && hasTagExp && isMeasurementIdGA4;\n } catch {\n if (typeof url === \"string\") {\n for (let j = 0; j < destinations.length; j++) {\n try {\n const target = getDuplicateEndpointUrl(destinations[j]);\n const targetNoQuery = target.origin + target.pathname;\n if (url.indexOf(targetNoQuery) !== -1) return false;\n } catch {\n // Intentionally empty\n }\n }\n\n const hasGtmFallback = url.indexOf(\"gtm=\") !== -1;\n const hasTagExpFallback = url.indexOf(\"tag_exp=\") !== -1;\n const idMatch = url.match(/[?&](?:tid|id)=G-[A-Za-z0-9]+/);\n return !!(hasGtmFallback && hasTagExpFallback && idMatch);\n }\n return false;\n }\n }\n\n function buildDuplicateUrl(originalUrl: string): string {\n const id = getMeasurementId(originalUrl);\n const dest = getDestinationForId(id);\n if (!dest) return \"\";\n\n const dst = getDuplicateEndpointUrl(dest);\n try {\n const src = new URL(originalUrl, location.href);\n dst.search = src.search;\n dst.searchParams.set(\"_dtv\", version);\n dst.searchParams.set(\"_dtn\", \"gd\");\n } catch {}\n return ensureBareQueryFlag(dst.toString(), \"richsstsse\");\n }\n\n function getConvertToGet(url: string): boolean {\n const id = getMeasurementId(url);\n const dest = getDestinationForId(id);\n return dest ? !!dest.convert_to_get : false;\n }\n\n const context: InterceptorContext = {\n debug: !!options.debug,\n isTargetUrl,\n buildDuplicateUrl,\n getConvertToGet,\n };\n\n const interceptors: NetworkInterceptor[] = [\n new FetchInterceptor(),\n new XhrInterceptor(),\n new BeaconInterceptor(),\n new ScriptInterceptor(),\n ];\n\n for (let i = 0; i < interceptors.length; i++) {\n try {\n interceptors[i].install(context);\n } catch (e) {\n if (options.debug) console.error(\"GA4 Duplicator: failed to install interceptor\", e);\n }\n }\n\n (window as any).__ga4DuplicatorInitialized = true;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["version", "options", "FetchInterceptor", "ctx", "originalFetch", "resource", "config", "requestUrl", "method", "upperMethod", "prepareBodyPromise", "e", "originalPromise", "duplicateUrl", "convertToGet", "error", "dupBody", "bodyStr", "lines", "sentAny", "i", "line", "mergedUrl", "urlWithMergedLine", "mergeBodyLineWithUrl", "XhrInterceptor", "originalXHROpen", "originalXHRSend", "url", "body", "originalResult", "dupErr", "BeaconInterceptor", "originalSendBeacon", "data", "ScriptInterceptor", "scriptSrcDescriptor", "originalScriptSrcSetter", "originalScriptSrcGetter", "originalScriptSetAttribute", "duplicateIfGA4Url", "urlString", "setter", "getter", "value", "last", "self", "onloadOnce", "finalUrl", "name", "v", "selfAttr", "onloadOnceAttr", "finalUrlAttr", "destinations", "dest", "normalizePath", "p", "matchesId", "pattern", "id", "regexStr", "ensureBareQueryFlag", "flag", "u", "f", "hashIdx", "beforeHash", "hash", "qIdx", "base", "rawQuery", "parts", "kept", "newQuery", "getMeasurementId", "parsed", "match", "getDestinationForId", "originalUrl", "bodyLine", "lineParams", "key", "urlWithoutQuery", "originalParams", "merged", "getDuplicateEndpointUrl", "trackingURL", "isTargetUrl", "duplicateTarget", "params", "hasGtm", "hasTagExp", "measurementId", "isMeasurementIdGA4", "j", "target", "targetNoQuery", "hasGtmFallback", "hasTagExpFallback", "idMatch", "buildDuplicateUrl", "dst", "src", "version", "getConvertToGet", "context", "interceptors"]
|
|
7
7
|
}
|
package/package.json
CHANGED
package/src.hash
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
17117454d817fdc6cd06ea872f1800180524a7c9e009756af13fa445a3baa9b8 -
|