@nuxt/scripts 1.0.0-beta.2 → 1.0.0-beta.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/README.md +3 -3
  2. package/dist/client/200.html +1 -1
  3. package/dist/client/404.html +1 -1
  4. package/dist/client/_nuxt/{DvH517bE.js → BlmrFwhD.js} +1 -1
  5. package/dist/client/_nuxt/{DfLgoB--.js → BwCYQWJt.js} +1 -1
  6. package/dist/client/_nuxt/DvbTvDd0.js +162 -0
  7. package/dist/client/_nuxt/{B66N9HCo.js → ZrewjUYk.js} +1 -1
  8. package/dist/client/_nuxt/builds/latest.json +1 -1
  9. package/dist/client/_nuxt/builds/meta/6660a023-888d-415f-b66d-ce774e6f8f11.json +1 -0
  10. package/dist/client/_nuxt/entry.CACgbLJl.css +1 -0
  11. package/dist/client/_nuxt/error-404.CHeaW3dp.css +1 -0
  12. package/dist/client/_nuxt/error-500.DvOvWme_.css +1 -0
  13. package/dist/client/index.html +1 -1
  14. package/dist/module.d.mts +27 -18
  15. package/dist/module.d.ts +178 -0
  16. package/dist/module.json +1 -1
  17. package/dist/module.mjs +763 -526
  18. package/dist/registry.d.ts +6 -0
  19. package/dist/registry.mjs +109 -21
  20. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.d.vue.ts +2 -2
  21. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue +7 -7
  22. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue.d.ts +2 -2
  23. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.vue +6 -6
  24. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsCircle.vue +7 -7
  25. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsHeatmapLayer.vue +6 -6
  26. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.vue +12 -12
  27. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue +6 -6
  28. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.d.vue.ts +1 -1
  29. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue +6 -6
  30. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue.d.ts +1 -1
  31. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.vue +5 -5
  32. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolygon.vue +7 -7
  33. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolyline.vue +7 -7
  34. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsRectangle.vue +7 -7
  35. package/dist/runtime/components/ScriptCrisp.vue +1 -1
  36. package/dist/runtime/components/ScriptGoogleAdsense.vue +1 -1
  37. package/dist/runtime/components/ScriptGravatar.d.vue.ts +22 -0
  38. package/dist/runtime/components/ScriptGravatar.vue +46 -0
  39. package/dist/runtime/components/ScriptGravatar.vue.d.ts +22 -0
  40. package/dist/runtime/components/ScriptInstagramEmbed.vue +1 -1
  41. package/dist/runtime/components/ScriptIntercom.vue +4 -3
  42. package/dist/runtime/components/ScriptPayPalButtons.d.vue.ts +43 -32
  43. package/dist/runtime/components/ScriptPayPalButtons.vue +48 -79
  44. package/dist/runtime/components/ScriptPayPalButtons.vue.d.ts +43 -32
  45. package/dist/runtime/components/ScriptPayPalMessages.d.vue.ts +37 -23
  46. package/dist/runtime/components/ScriptPayPalMessages.vue +46 -50
  47. package/dist/runtime/components/ScriptPayPalMessages.vue.d.ts +37 -23
  48. package/dist/runtime/components/ScriptStripePricingTable.vue +2 -2
  49. package/dist/runtime/components/ScriptVimeoPlayer.d.vue.ts +9 -0
  50. package/dist/runtime/components/ScriptVimeoPlayer.vue +13 -10
  51. package/dist/runtime/components/ScriptVimeoPlayer.vue.d.ts +9 -0
  52. package/dist/runtime/components/ScriptXEmbed.d.vue.ts +1 -1
  53. package/dist/runtime/components/ScriptXEmbed.vue +1 -1
  54. package/dist/runtime/components/ScriptXEmbed.vue.d.ts +1 -1
  55. package/dist/runtime/components/ScriptYouTubePlayer.d.vue.ts +2 -2
  56. package/dist/runtime/components/ScriptYouTubePlayer.vue +11 -5
  57. package/dist/runtime/components/ScriptYouTubePlayer.vue.d.ts +2 -2
  58. package/dist/runtime/composables/useScript.js +11 -6
  59. package/dist/runtime/composables/useScriptEventPage.js +2 -2
  60. package/dist/runtime/composables/useScriptTriggerConsent.js +1 -1
  61. package/dist/runtime/composables/useScriptTriggerElement.js +1 -1
  62. package/dist/runtime/composables/useScriptTriggerIdleTimeout.js +1 -1
  63. package/dist/runtime/registry/clarity.d.ts +10 -15
  64. package/dist/runtime/registry/clarity.js +22 -31
  65. package/dist/runtime/registry/cloudflare-web-analytics.d.ts +2 -13
  66. package/dist/runtime/registry/cloudflare-web-analytics.js +2 -14
  67. package/dist/runtime/registry/crisp.d.ts +9 -39
  68. package/dist/runtime/registry/crisp.js +2 -33
  69. package/dist/runtime/registry/databuddy-analytics.d.ts +2 -35
  70. package/dist/runtime/registry/databuddy-analytics.js +20 -45
  71. package/dist/runtime/registry/fathom-analytics.d.ts +6 -25
  72. package/dist/runtime/registry/fathom-analytics.js +2 -24
  73. package/dist/runtime/registry/google-adsense.d.ts +2 -10
  74. package/dist/runtime/registry/google-adsense.js +2 -11
  75. package/dist/runtime/registry/google-analytics.d.ts +3 -5
  76. package/dist/runtime/registry/google-analytics.js +3 -8
  77. package/dist/runtime/registry/google-maps.d.ts +3 -9
  78. package/dist/runtime/registry/google-maps.js +2 -8
  79. package/dist/runtime/registry/google-recaptcha.d.ts +2 -6
  80. package/dist/runtime/registry/google-recaptcha.js +4 -12
  81. package/dist/runtime/registry/google-sign-in.d.ts +2 -13
  82. package/dist/runtime/registry/google-sign-in.js +2 -22
  83. package/dist/runtime/registry/google-tag-manager.d.ts +3 -28
  84. package/dist/runtime/registry/google-tag-manager.js +4 -27
  85. package/dist/runtime/registry/gravatar.d.ts +25 -0
  86. package/dist/runtime/registry/gravatar.js +32 -0
  87. package/dist/runtime/registry/hotjar.d.ts +3 -5
  88. package/dist/runtime/registry/hotjar.js +2 -5
  89. package/dist/runtime/registry/instagram-embed.d.ts +2 -17
  90. package/dist/runtime/registry/instagram-embed.js +4 -19
  91. package/dist/runtime/registry/intercom.d.ts +3 -11
  92. package/dist/runtime/registry/intercom.js +2 -12
  93. package/dist/runtime/registry/matomo-analytics.d.ts +2 -11
  94. package/dist/runtime/registry/matomo-analytics.js +3 -12
  95. package/dist/runtime/registry/meta-pixel.d.ts +3 -5
  96. package/dist/runtime/registry/meta-pixel.js +2 -4
  97. package/dist/runtime/registry/npm.d.ts +2 -6
  98. package/dist/runtime/registry/npm.js +2 -9
  99. package/dist/runtime/registry/paypal.d.ts +4 -25
  100. package/dist/runtime/registry/paypal.js +3 -66
  101. package/dist/runtime/registry/plausible-analytics.js +18 -13
  102. package/dist/runtime/registry/posthog.d.ts +10 -11
  103. package/dist/runtime/registry/posthog.js +7 -20
  104. package/dist/runtime/registry/reddit-pixel.d.ts +4 -5
  105. package/dist/runtime/registry/reddit-pixel.js +2 -4
  106. package/dist/runtime/registry/rybbit-analytics.d.ts +2 -14
  107. package/dist/runtime/registry/rybbit-analytics.js +7 -19
  108. package/dist/runtime/registry/schemas.d.ts +946 -0
  109. package/dist/runtime/registry/schemas.js +901 -0
  110. package/dist/runtime/registry/segment.d.ts +2 -5
  111. package/dist/runtime/registry/segment.js +2 -5
  112. package/dist/runtime/registry/snapchat-pixel.d.ts +3 -32
  113. package/dist/runtime/registry/snapchat-pixel.js +2 -20
  114. package/dist/runtime/registry/stripe.d.ts +3 -4
  115. package/dist/runtime/registry/stripe.js +2 -4
  116. package/dist/runtime/registry/tiktok-pixel.d.ts +3 -6
  117. package/dist/runtime/registry/tiktok-pixel.js +2 -6
  118. package/dist/runtime/registry/umami-analytics.d.ts +2 -31
  119. package/dist/runtime/registry/umami-analytics.js +2 -36
  120. package/dist/runtime/registry/vercel-analytics.d.ts +29 -0
  121. package/dist/runtime/registry/vercel-analytics.js +84 -0
  122. package/dist/runtime/registry/vimeo-player.d.ts +2 -2
  123. package/dist/runtime/registry/vimeo-player.js +1 -1
  124. package/dist/runtime/registry/x-embed.d.ts +2 -16
  125. package/dist/runtime/registry/x-embed.js +2 -17
  126. package/dist/runtime/registry/x-pixel.d.ts +3 -6
  127. package/dist/runtime/registry/x-pixel.js +2 -5
  128. package/dist/runtime/registry/youtube-player.d.ts +7 -7
  129. package/dist/runtime/registry/youtube-player.js +1 -1
  130. package/dist/runtime/server/google-static-maps-proxy.js +1 -1
  131. package/dist/runtime/server/{sw-handler.d.ts → gravatar-proxy.d.ts} +1 -1
  132. package/dist/runtime/server/gravatar-proxy.js +62 -0
  133. package/dist/runtime/server/instagram-embed-asset.js +2 -1
  134. package/dist/runtime/server/instagram-embed-image.js +2 -1
  135. package/dist/runtime/server/instagram-embed.js +22 -13
  136. package/dist/runtime/server/proxy-handler.js +161 -117
  137. package/dist/runtime/server/utils/privacy.d.ts +45 -1
  138. package/dist/runtime/server/utils/privacy.js +103 -40
  139. package/dist/runtime/server/x-embed.js +3 -2
  140. package/dist/runtime/types.d.ts +35 -24
  141. package/dist/runtime/utils/pure.d.ts +0 -4
  142. package/dist/runtime/utils/pure.js +0 -67
  143. package/dist/runtime/utils.d.ts +3 -3
  144. package/dist/runtime/utils.js +12 -7
  145. package/dist/shared/scripts.Crpn87WB.mjs +318 -0
  146. package/dist/stats.d.mts +39 -0
  147. package/dist/stats.d.ts +39 -0
  148. package/dist/stats.mjs +772 -0
  149. package/dist/types-source.d.mts +19 -0
  150. package/dist/types-source.d.ts +19 -0
  151. package/dist/types-source.mjs +975 -0
  152. package/package.json +42 -31
  153. package/dist/client/_nuxt/B8XOar-X.js +0 -162
  154. package/dist/client/_nuxt/builds/meta/133a46c5-a5c1-4a63-87d1-037947a5bcdb.json +0 -1
  155. package/dist/client/_nuxt/entry.D45OuV0w.css +0 -1
  156. package/dist/client/_nuxt/error-404.B57D-jUQ.css +0 -1
  157. package/dist/client/_nuxt/error-500.DTHUW7BI.css +0 -1
  158. package/dist/runtime/components/ScriptPayPalMarks.d.vue.ts +0 -52
  159. package/dist/runtime/components/ScriptPayPalMarks.vue +0 -69
  160. package/dist/runtime/components/ScriptPayPalMarks.vue.d.ts +0 -52
  161. package/dist/runtime/plugins/sw-register.client.d.ts +0 -2
  162. package/dist/runtime/plugins/sw-register.client.js +0 -12
  163. package/dist/runtime/server/sw-handler.js +0 -25
  164. package/dist/runtime/sw/proxy-sw.template.d.ts +0 -1
  165. package/dist/runtime/sw/proxy-sw.template.js +0 -54
@@ -1,3 +1,40 @@
1
+ const FULL_PRIVACY = { ip: true, userAgent: true, language: true, screen: true, timezone: true, hardware: true };
2
+ const NO_PRIVACY = { ip: false, userAgent: false, language: false, screen: false, timezone: false, hardware: false };
3
+ const MAJOR_VERSION_RE = /^(\d+)/;
4
+ const VERSION_RE = /^(\d+)(([.\-_])\d+)*/;
5
+ const VERSION_SPLIT_RE = /[.\-_]/;
6
+ const SNAPCHAT_VERSION_RE = /("version"\s*:\s*")(\d+(?:\.\d+)*)/g;
7
+ const GA_VERSION_RE = /;(\d+(?:\.\d+)*)/g;
8
+ const UPPERCASE_RE = /^[A-Z]/;
9
+ const LANG_CODE_RE = /^[a-z]{2}(?:-[a-z]{2,})?$/i;
10
+ export function resolvePrivacy(input) {
11
+ if (input === true)
12
+ return { ...FULL_PRIVACY };
13
+ if (input === false || input === void 0 || input === null)
14
+ return { ...NO_PRIVACY };
15
+ return {
16
+ ip: input.ip ?? false,
17
+ userAgent: input.userAgent ?? false,
18
+ language: input.language ?? false,
19
+ screen: input.screen ?? false,
20
+ timezone: input.timezone ?? false,
21
+ hardware: input.hardware ?? false
22
+ };
23
+ }
24
+ export function mergePrivacy(base, override) {
25
+ if (override === void 0 || override === null)
26
+ return base;
27
+ if (typeof override === "boolean")
28
+ return resolvePrivacy(override);
29
+ return {
30
+ ip: override.ip !== void 0 ? override.ip : base.ip,
31
+ userAgent: override.userAgent !== void 0 ? override.userAgent : base.userAgent,
32
+ language: override.language !== void 0 ? override.language : base.language,
33
+ screen: override.screen !== void 0 ? override.screen : base.screen,
34
+ timezone: override.timezone !== void 0 ? override.timezone : base.timezone,
35
+ hardware: override.hardware !== void 0 ? override.hardware : base.hardware
36
+ };
37
+ }
1
38
  export const IP_HEADERS = [
2
39
  "x-forwarded-for",
3
40
  "x-real-ip",
@@ -55,7 +92,7 @@ export const NORMALIZE_PARAMS = {
55
92
  };
56
93
  export function anonymizeIP(ip) {
57
94
  if (ip.includes(":")) {
58
- return ip.split(":").slice(0, 3).join(":") + "::";
95
+ return `${ip.split(":").slice(0, 3).join(":")}::`;
59
96
  }
60
97
  const parts = ip.split(".");
61
98
  if (parts.length === 4) {
@@ -77,7 +114,7 @@ export function normalizeUserAgent(ua) {
77
114
  const idx = ua.indexOf(pattern);
78
115
  if (idx !== -1) {
79
116
  const versionStart = idx + pattern.length;
80
- const majorVersion = ua.slice(versionStart).match(/^(\d+)/)?.[1];
117
+ const majorVersion = ua.slice(versionStart).match(MAJOR_VERSION_RE)?.[1];
81
118
  if (majorVersion)
82
119
  return `Mozilla/5.0 (compatible; ${family}/${majorVersion}.0)`;
83
120
  }
@@ -93,8 +130,10 @@ const SCREEN_BUCKETS = {
93
130
  mobile: { w: 360, h: 640 }
94
131
  };
95
132
  function getDeviceClass(width) {
96
- if (width >= 1200) return "desktop";
97
- if (width >= 700) return "tablet";
133
+ if (width >= 1200)
134
+ return "desktop";
135
+ if (width >= 700)
136
+ return "tablet";
98
137
  return "mobile";
99
138
  }
100
139
  export function generalizeScreen(value, dimension) {
@@ -113,31 +152,38 @@ export function generalizeScreen(value, dimension) {
113
152
  }
114
153
  export function generalizeHardware(value) {
115
154
  const num = typeof value === "number" ? value : Number(value);
116
- if (Number.isNaN(num)) return 4;
117
- if (num >= 16) return 16;
118
- if (num >= 8) return 8;
119
- if (num >= 4) return 4;
155
+ if (Number.isNaN(num))
156
+ return 4;
157
+ if (num >= 16)
158
+ return 16;
159
+ if (num >= 8)
160
+ return 8;
161
+ if (num >= 4)
162
+ return 4;
120
163
  return 2;
121
164
  }
122
165
  export function generalizeVersion(value) {
123
- if (typeof value !== "string") return String(value);
124
- const match = value.match(/^(\d+)(([.\-_])\d+)*/);
125
- if (!match) return String(value);
166
+ if (typeof value !== "string")
167
+ return String(value);
168
+ const match = value.match(VERSION_RE);
169
+ if (!match)
170
+ return String(value);
126
171
  const major = match[1];
127
172
  const sep = match[3] || ".";
128
- const segmentCount = value.split(/[.\-_]/).length;
129
- return major + (sep + "0").repeat(segmentCount - 1);
173
+ const segmentCount = value.split(VERSION_SPLIT_RE).length;
174
+ return major + `${sep}0`.repeat(segmentCount - 1);
130
175
  }
131
176
  export function generalizeBrowserVersions(value) {
132
- if (typeof value !== "string") return String(value);
177
+ if (typeof value !== "string")
178
+ return String(value);
133
179
  const zeroSegments = (ver) => {
134
180
  const parts = ver.split(".");
135
181
  return parts[0] + parts.slice(1).map(() => ".0").join("");
136
182
  };
137
183
  if (value.includes('"version"'))
138
- return value.replace(/("version"\s*:\s*")(\d+(?:\.\d+)*)/g, (_, prefix, ver) => prefix + zeroSegments(ver));
184
+ return value.replace(SNAPCHAT_VERSION_RE, (_, prefix, ver) => prefix + zeroSegments(ver));
139
185
  if (value.includes(";"))
140
- return value.replace(/;(\d+(?:\.\d+)*)/g, (_, ver) => ";" + zeroSegments(ver));
186
+ return value.replace(GA_VERSION_RE, (_, ver) => `;${zeroSegments(ver)}`);
141
187
  return value;
142
188
  }
143
189
  export function generalizeTimezone(value) {
@@ -152,15 +198,16 @@ export function generalizeTimezone(value) {
152
198
  export function anonymizeDeviceInfo(value) {
153
199
  const sep = value.includes("|") ? "|" : "&";
154
200
  const parts = value.split(sep);
155
- if (parts.length < 4) return value;
201
+ if (parts.length < 4)
202
+ return value;
156
203
  const result = [...parts];
157
204
  for (let i = 0; i < parts.length; i++) {
158
205
  const part = parts[i];
159
- if (part.includes("/") && /^[A-Z]/.test(part)) {
206
+ if (part.includes("/") && UPPERCASE_RE.test(part)) {
160
207
  result[i] = String(generalizeTimezone(part));
161
208
  continue;
162
209
  }
163
- if (/^[a-z]{2}(?:-[a-z]{2,})?$/i.test(part)) {
210
+ if (LANG_CODE_RE.test(part)) {
164
211
  result[i] = normalizeLanguage(part);
165
212
  continue;
166
213
  }
@@ -183,35 +230,51 @@ export function anonymizeDeviceInfo(value) {
183
230
  }
184
231
  return result.join(sep);
185
232
  }
186
- export function stripPayloadFingerprinting(payload) {
233
+ export function stripPayloadFingerprinting(payload, privacy) {
234
+ const p = privacy || FULL_PRIVACY;
187
235
  const result = {};
188
236
  let deviceClass;
189
237
  for (const [key, value] of Object.entries(payload)) {
190
238
  if (key.toLowerCase() === "sw") {
191
239
  const num = typeof value === "number" ? value : Number(value);
192
- if (!Number.isNaN(num)) deviceClass = getDeviceClass(num);
240
+ if (!Number.isNaN(num))
241
+ deviceClass = getDeviceClass(num);
193
242
  }
194
243
  }
195
244
  for (const [key, value] of Object.entries(payload)) {
196
245
  const lowerKey = key.toLowerCase();
197
- const isLanguageParam = NORMALIZE_PARAMS.language.some((p) => lowerKey === p.toLowerCase());
198
- const isUserAgentParam = NORMALIZE_PARAMS.userAgent.some((p) => lowerKey === p.toLowerCase());
199
- if ((isLanguageParam || isUserAgentParam) && typeof value === "string") {
200
- result[key] = isLanguageParam ? normalizeLanguage(value) : normalizeUserAgent(value);
201
- continue;
202
- }
203
246
  const matchesParam = (key2, params) => {
204
247
  const lk = key2.toLowerCase();
205
- return params.some((p) => {
206
- const lp = p.toLowerCase();
207
- return lk === lp || lk.startsWith(lp + "[");
248
+ return params.some((pm) => {
249
+ const lp = pm.toLowerCase();
250
+ return lk === lp || lk.startsWith(`${lp}[`);
208
251
  });
209
252
  };
253
+ const isLanguageParam = NORMALIZE_PARAMS.language.some((pm) => lowerKey === pm.toLowerCase());
254
+ if (isLanguageParam) {
255
+ if (Array.isArray(value)) {
256
+ result[key] = p.language ? value.map((v) => typeof v === "string" ? normalizeLanguage(v) : v) : value;
257
+ } else if (typeof value === "string") {
258
+ result[key] = p.language ? normalizeLanguage(value) : value;
259
+ } else {
260
+ result[key] = value;
261
+ }
262
+ continue;
263
+ }
264
+ const isUserAgentParam = NORMALIZE_PARAMS.userAgent.some((pm) => lowerKey === pm.toLowerCase());
265
+ if (isUserAgentParam && typeof value === "string") {
266
+ result[key] = p.userAgent ? normalizeUserAgent(value) : value;
267
+ continue;
268
+ }
210
269
  if (matchesParam(key, STRIP_PARAMS.ip) && typeof value === "string") {
211
- result[key] = anonymizeIP(value);
270
+ result[key] = p.ip ? anonymizeIP(value) : value;
212
271
  continue;
213
272
  }
214
273
  if (matchesParam(key, STRIP_PARAMS.screen)) {
274
+ if (!p.screen) {
275
+ result[key] = value;
276
+ continue;
277
+ }
215
278
  if (["sd", "colordepth", "pixelratio"].includes(lowerKey)) {
216
279
  result[key] = value;
217
280
  } else if (lowerKey === "sh" && deviceClass) {
@@ -223,31 +286,31 @@ export function stripPayloadFingerprinting(payload) {
223
286
  continue;
224
287
  }
225
288
  if (matchesParam(key, STRIP_PARAMS.hardware)) {
226
- result[key] = generalizeHardware(value);
289
+ result[key] = p.screen ? generalizeHardware(value) : value;
227
290
  continue;
228
291
  }
229
292
  if (matchesParam(key, STRIP_PARAMS.version)) {
230
- result[key] = generalizeVersion(value);
293
+ result[key] = p.hardware ? generalizeVersion(value) : value;
231
294
  continue;
232
295
  }
233
296
  if (matchesParam(key, STRIP_PARAMS.browserVersion)) {
234
- result[key] = generalizeBrowserVersions(value);
297
+ result[key] = p.hardware ? generalizeBrowserVersions(value) : value;
235
298
  continue;
236
299
  }
237
300
  if (matchesParam(key, STRIP_PARAMS.location)) {
238
- result[key] = generalizeTimezone(value);
301
+ result[key] = p.timezone ? generalizeTimezone(value) : value;
239
302
  continue;
240
303
  }
241
304
  if (matchesParam(key, STRIP_PARAMS.browserData)) {
242
- result[key] = Array.isArray(value) ? [] : "";
305
+ result[key] = p.hardware ? Array.isArray(value) ? [] : "" : value;
243
306
  continue;
244
307
  }
245
308
  if (matchesParam(key, STRIP_PARAMS.canvas)) {
246
- result[key] = typeof value === "number" ? 0 : typeof value === "object" ? {} : "";
309
+ result[key] = p.hardware ? typeof value === "number" ? 0 : typeof value === "object" ? {} : "" : value;
247
310
  continue;
248
311
  }
249
312
  if (matchesParam(key, STRIP_PARAMS.deviceInfo)) {
250
- result[key] = typeof value === "string" ? anonymizeDeviceInfo(value) : "";
313
+ result[key] = p.hardware ? typeof value === "string" ? anonymizeDeviceInfo(value) : "" : value;
251
314
  continue;
252
315
  }
253
316
  if (matchesParam(key, STRIP_PARAMS.platform)) {
@@ -256,10 +319,10 @@ export function stripPayloadFingerprinting(payload) {
256
319
  }
257
320
  if (Array.isArray(value)) {
258
321
  result[key] = value.map(
259
- (item) => typeof item === "object" && item !== null ? stripPayloadFingerprinting(item) : item
322
+ (item) => typeof item === "object" && item !== null ? stripPayloadFingerprinting(item, privacy) : item
260
323
  );
261
324
  } else if (typeof value === "object" && value !== null) {
262
- result[key] = stripPayloadFingerprinting(value);
325
+ result[key] = stripPayloadFingerprinting(value, privacy);
263
326
  } else {
264
327
  result[key] = value;
265
328
  }
@@ -1,15 +1,16 @@
1
1
  import { createError, defineEventHandler, getQuery, setHeader } from "h3";
2
2
  import { $fetch } from "ofetch";
3
+ const TWEET_ID_RE = /^\d+$/;
3
4
  export default defineEventHandler(async (event) => {
4
5
  const query = getQuery(event);
5
6
  const tweetId = query.id;
6
- if (!tweetId || !/^\d+$/.test(tweetId)) {
7
+ if (!tweetId || !TWEET_ID_RE.test(tweetId)) {
7
8
  throw createError({
8
9
  statusCode: 400,
9
10
  statusMessage: "Valid Tweet ID is required"
10
11
  });
11
12
  }
12
- const randomToken = [...Array(11)].map(() => (Math.random() * 36).toString(36)[2]).join("");
13
+ const randomToken = Array.from(Array.from({ length: 11 }), () => (Math.random() * 36).toString(36)[2]).join("");
13
14
  const params = new URLSearchParams({ id: tweetId, token: randomToken });
14
15
  const tweetData = await $fetch(
15
16
  `https://cdn.syndication.twimg.com/tweet-result?${params.toString()}`,
@@ -1,37 +1,40 @@
1
+ import type { UseScriptInput, UseScriptOptions, VueScriptInstance } from '@unhead/vue';
1
2
  import type { Script } from '@unhead/vue/types';
2
- import type { UseScriptInput, VueScriptInstance, UseScriptOptions } from '@unhead/vue';
3
- import type { ComputedRef, Ref } from 'vue';
4
- import type { InferInput, ObjectSchema, ValiError } from 'valibot';
5
3
  import type { Import } from 'unimport';
6
- import type { SegmentInput } from './registry/segment.js';
4
+ import type { InferInput, ObjectSchema, UnionSchema, ValiError } from 'valibot';
5
+ import type { ComputedRef, Ref } from 'vue';
6
+ import type { ClarityInput } from './registry/clarity.js';
7
7
  import type { CloudflareWebAnalyticsInput } from './registry/cloudflare-web-analytics.js';
8
+ import type { CrispInput } from './registry/crisp.js';
8
9
  import type { DatabuddyAnalyticsInput } from './registry/databuddy-analytics.js';
9
- import type { MetaPixelInput } from './registry/meta-pixel.js';
10
10
  import type { FathomAnalyticsInput } from './registry/fathom-analytics.js';
11
+ import type { GoogleAdsenseInput } from './registry/google-adsense.js';
12
+ import type { GoogleAnalyticsInput } from './registry/google-analytics.js';
13
+ import type { GoogleMapsInput } from './registry/google-maps.js';
14
+ import type { GoogleRecaptchaInput } from './registry/google-recaptcha.js';
15
+ import type { GoogleSignInInput } from './registry/google-sign-in.js';
16
+ import type { GoogleTagManagerInput } from './registry/google-tag-manager.js';
17
+ import type { GravatarInput } from './registry/gravatar.js';
11
18
  import type { HotjarInput } from './registry/hotjar.js';
12
19
  import type { IntercomInput } from './registry/intercom.js';
13
- import type { GoogleMapsInput } from './registry/google-maps.js';
20
+ import type { LemonSqueezyInput } from './registry/lemon-squeezy.js';
14
21
  import type { MatomoAnalyticsInput } from './registry/matomo-analytics.js';
15
- import type { StripeInput } from './registry/stripe.js';
16
- import type { VimeoPlayerInput } from './registry/vimeo-player.js';
17
- import type { XPixelInput } from './registry/x-pixel.js';
18
- import type { SnapTrPixelInput } from './registry/snapchat-pixel.js';
19
- import type { YouTubePlayerInput } from './registry/youtube-player.js';
20
- import type { PlausibleAnalyticsInput } from './registry/plausible-analytics.js';
22
+ import type { MetaPixelInput } from './registry/meta-pixel.js';
21
23
  import type { NpmInput } from './registry/npm.js';
22
- import type { LemonSqueezyInput } from './registry/lemon-squeezy.js';
23
- import type { GoogleAdsenseInput } from './registry/google-adsense.js';
24
- import type { ClarityInput } from './registry/clarity.js';
25
- import type { CrispInput } from './registry/crisp.js';
26
- import type { GoogleAnalyticsInput } from './registry/google-analytics.js';
27
- import type { GoogleTagManagerInput } from './registry/google-tag-manager.js';
28
- import type { UmamiAnalyticsInput } from './registry/umami-analytics.js';
29
- import type { RybbitAnalyticsInput } from './registry/rybbit-analytics.js';
30
- import type { RedditPixelInput } from './registry/reddit-pixel.js';
31
24
  import type { PayPalInput } from './registry/paypal.js';
25
+ import type { PlausibleAnalyticsInput } from './registry/plausible-analytics.js';
32
26
  import type { PostHogInput } from './registry/posthog.js';
33
- import type { GoogleRecaptchaInput } from './registry/google-recaptcha.js';
27
+ import type { RedditPixelInput } from './registry/reddit-pixel.js';
28
+ import type { RybbitAnalyticsInput } from './registry/rybbit-analytics.js';
29
+ import type { SegmentInput } from './registry/segment.js';
30
+ import type { SnapTrPixelInput } from './registry/snapchat-pixel.js';
31
+ import type { StripeInput } from './registry/stripe.js';
34
32
  import type { TikTokPixelInput } from './registry/tiktok-pixel.js';
33
+ import type { UmamiAnalyticsInput } from './registry/umami-analytics.js';
34
+ import type { VercelAnalyticsInput } from './registry/vercel-analytics.js';
35
+ import type { VimeoPlayerInput } from './registry/vimeo-player.js';
36
+ import type { XPixelInput } from './registry/x-pixel.js';
37
+ import type { YouTubePlayerInput } from './registry/youtube-player.js';
35
38
  export type WarmupStrategy = false | 'preload' | 'preconnect' | 'dns-prefetch';
36
39
  export type UseScriptContext<T extends Record<symbol | string, any>> = VueScriptInstance<T> & {
37
40
  /**
@@ -163,6 +166,7 @@ export interface ScriptRegistry {
163
166
  googleAnalytics?: GoogleAnalyticsInput;
164
167
  googleMaps?: GoogleMapsInput;
165
168
  googleRecaptcha?: GoogleRecaptchaInput;
169
+ googleSignIn?: GoogleSignInInput;
166
170
  lemonSqueezy?: LemonSqueezyInput;
167
171
  googleTagManager?: GoogleTagManagerInput;
168
172
  hotjar?: HotjarInput;
@@ -178,21 +182,23 @@ export interface ScriptRegistry {
178
182
  xPixel?: XPixelInput;
179
183
  snapchatPixel?: SnapTrPixelInput;
180
184
  youtubePlayer?: YouTubePlayerInput;
185
+ vercelAnalytics?: VercelAnalyticsInput;
181
186
  vimeoPlayer?: VimeoPlayerInput;
182
187
  umamiAnalytics?: UmamiAnalyticsInput;
188
+ gravatar?: GravatarInput;
183
189
  [key: `${string}-npm`]: NpmInput;
184
190
  }
185
191
  export type NuxtConfigScriptRegistryEntry<T> = true | 'mock' | T | [T, NuxtUseScriptOptionsSerializable];
186
192
  export type NuxtConfigScriptRegistry<T extends keyof ScriptRegistry = keyof ScriptRegistry> = Partial<{
187
193
  [key in T]: NuxtConfigScriptRegistryEntry<ScriptRegistry[key]>;
188
- }>;
194
+ }> & Record<string & {}, NuxtConfigScriptRegistryEntry<any>>;
189
195
  export type UseFunctionType<T, U> = T extends {
190
196
  use: infer V;
191
197
  } ? V extends (...args: any) => any ? ReturnType<V> : U : U;
192
198
  declare const _emptyOptions: ObjectSchema<{}, undefined>;
193
199
  export type EmptyOptionsSchema = typeof _emptyOptions;
194
200
  type ScriptInput = Script;
195
- export type InferIfSchema<T> = T extends ObjectSchema<any, any> ? InferInput<T> : T;
201
+ export type InferIfSchema<T> = T extends ObjectSchema<any, any> | UnionSchema<any, any> ? InferInput<T> : T;
196
202
  export type RegistryScriptInput<T = EmptyOptionsSchema, Bundelable extends boolean = true, Usable extends boolean = false, CanBypassOptions extends boolean = true> = (InferIfSchema<T> & {
197
203
  /**
198
204
  * A unique key to use for the script, this can be used to load multiple of the same script with different options.
@@ -209,6 +215,11 @@ export type RegistryScriptInput<T = EmptyOptionsSchema, Bundelable extends boole
209
215
  scriptOptions?: Omit<NuxtUseScriptOptions, Bundelable extends true ? '' : 'bundle' | Usable extends true ? '' : 'use'>;
210
216
  } : never);
211
217
  export interface RegistryScript {
218
+ /**
219
+ * The config key used in `scripts.registry` in nuxt.config (e.g., 'googleAnalytics', 'plausibleAnalytics').
220
+ * Used for direct lookup from config to script — avoids fragile import name convention matching.
221
+ */
222
+ registryKey?: string;
212
223
  import?: Import;
213
224
  scriptBundling?: false | ((options?: any) => string | false);
214
225
  /**
@@ -7,7 +7,3 @@ export interface ProxyRewrite {
7
7
  /** Local path to rewrite to (e.g., '/_scripts/c/ga/g/collect') */
8
8
  to: string;
9
9
  }
10
- /**
11
- * Rewrite URLs in script content based on proxy config.
12
- */
13
- export declare function rewriteScriptUrls(content: string, rewrites: ProxyRewrite[]): string;
@@ -1,67 +0,0 @@
1
- import { parseURL, joinURL } from "ufo";
2
- export function rewriteScriptUrls(content, rewrites) {
3
- let result = content;
4
- const literalRegex = /(['"`])(.*?)\1/g;
5
- for (const { from, to } of rewrites) {
6
- const isSuffixMatch = from.startsWith(".");
7
- const fromSlashIdx = from.indexOf("/");
8
- const fromHost = fromSlashIdx > 0 ? from.slice(0, fromSlashIdx) : from;
9
- const fromPath = fromSlashIdx > 0 ? from.slice(fromSlashIdx) : "";
10
- result = result.replace(literalRegex, (match, quote, inner) => {
11
- if (!inner.includes(fromHost)) return match;
12
- const url = parseURL(inner);
13
- let shouldRewrite = false;
14
- let rewriteSuffix = "";
15
- if (url.host) {
16
- const hostMatches = isSuffixMatch ? url.host.endsWith(fromHost) : url.host === fromHost;
17
- if (hostMatches) {
18
- const fullPath = url.pathname + (url.search || "") + (url.hash || "");
19
- if (fromPath && fullPath.startsWith(fromPath)) {
20
- shouldRewrite = true;
21
- rewriteSuffix = fullPath.slice(fromPath.length);
22
- } else if (!fromPath) {
23
- shouldRewrite = true;
24
- rewriteSuffix = fullPath;
25
- }
26
- }
27
- } else if (inner.startsWith("//")) {
28
- const hostPart = inner.slice(2).split("/")[0];
29
- const hostMatches = isSuffixMatch ? hostPart?.endsWith(fromHost) ?? false : hostPart === fromHost;
30
- if (hostMatches) {
31
- const remainder = inner.slice(2 + (hostPart?.length ?? 0));
32
- if (fromPath && remainder.startsWith(fromPath)) {
33
- shouldRewrite = true;
34
- rewriteSuffix = remainder.slice(fromPath.length);
35
- } else if (!fromPath) {
36
- shouldRewrite = true;
37
- rewriteSuffix = remainder;
38
- }
39
- }
40
- } else if (fromPath && inner.startsWith(from) || isSuffixMatch && inner.includes(from)) {
41
- const domainEnd = inner.indexOf(from) + from.length;
42
- const nextChar = inner[domainEnd];
43
- if (!nextChar || nextChar === "/" || nextChar === "?" || nextChar === "#") {
44
- shouldRewrite = true;
45
- rewriteSuffix = inner.slice(domainEnd);
46
- }
47
- }
48
- if (shouldRewrite) {
49
- const rewritten = rewriteSuffix === "/" || rewriteSuffix.startsWith("?") || rewriteSuffix.startsWith("#") ? to + rewriteSuffix : joinURL(to, rewriteSuffix);
50
- return quote + rewritten + quote;
51
- }
52
- return match;
53
- });
54
- }
55
- const gaRewrite = rewrites.find((r) => r.from.includes("google-analytics.com/g/collect"));
56
- if (gaRewrite) {
57
- result = result.replace(
58
- /"https:\/\/"\+\(.*?\)\+"\.google-analytics\.com\/g\/collect"/g,
59
- `"${gaRewrite.to}"`
60
- );
61
- result = result.replace(
62
- /"https:\/\/"\+\(.*?\)\+"\.analytics\.google\.com\/g\/collect"/g,
63
- `"${gaRewrite.to}"`
64
- );
65
- }
66
- return result;
67
- }
@@ -1,6 +1,6 @@
1
- import type { ObjectSchema } from 'valibot';
1
+ import type { EmptyOptionsSchema, InferIfSchema, NuxtUseScriptOptions, RegistryScriptInput, ScriptRegistry, UseFunctionType, UseScriptContext } from '#nuxt-scripts/types';
2
2
  import type { UseScriptInput } from '@unhead/vue';
3
- import type { EmptyOptionsSchema, InferIfSchema, NuxtUseScriptOptions, RegistryScriptInput, UseFunctionType, ScriptRegistry, UseScriptContext } from '#nuxt-scripts/types';
3
+ import type { ObjectSchema, UnionSchema } from 'valibot';
4
4
  export type MaybePromise<T> = Promise<T> | T;
5
5
  type OptionsFn<O> = (options: InferIfSchema<O>, ctx: {
6
6
  scriptInput?: UseScriptInput & {
@@ -9,7 +9,7 @@ type OptionsFn<O> = (options: InferIfSchema<O>, ctx: {
9
9
  }) => ({
10
10
  scriptInput?: UseScriptInput;
11
11
  scriptOptions?: NuxtUseScriptOptions;
12
- schema?: O extends ObjectSchema<any, any> ? O : undefined;
12
+ schema?: O extends ObjectSchema<any, any> | UnionSchema<any, any> ? O : undefined;
13
13
  clientInit?: () => void | Promise<any>;
14
14
  scriptMode?: 'external' | 'npm';
15
15
  });
@@ -1,9 +1,13 @@
1
+ import { parse } from "#nuxt-scripts-validator";
1
2
  import { defu } from "defu";
2
3
  import { useRuntimeConfig } from "nuxt/app";
3
- import { parseURL, withQuery, parseQuery } from "ufo";
4
+ import { parseQuery, parseURL, withQuery } from "ufo";
4
5
  import { useScript } from "./composables/useScript.js";
5
6
  import { createNpmScriptStub } from "./npm-script-stub.js";
6
- import { parse } from "#nuxt-scripts-validator";
7
+ const URL_MATCH_RE = /https?:\/\/[^/]+\/_nuxt\/(.+\.vue)(?:\?[^)]*)?:(\d+):(\d+)/;
8
+ const URL_PAREN_MATCH_RE = /\(https?:\/\/[^/]+\/_nuxt\/(.+\.vue)(?:\?[^)]*)?:(\d+):(\d+)\)/;
9
+ const VUE_MATCH_RE = /([^/\s]+\.vue):(\d+):(\d+)/;
10
+ const CLEAN_CALLER_RE = /^\s*at\s+/;
7
11
  function validateScriptInputSchema(key, schema, options) {
8
12
  if (import.meta.dev) {
9
13
  try {
@@ -54,25 +58,26 @@ export function useRegistryScript(registryKey, optionsFn, _userOptions) {
54
58
  );
55
59
  let loadedFrom = "unknown";
56
60
  if (callerLine) {
57
- const urlMatch = callerLine.match(/https?:\/\/[^/]+\/_nuxt\/(.+\.vue)(?:\?[^)]*)?:(\d+):(\d+)/) || callerLine.match(/\(https?:\/\/[^/]+\/_nuxt\/(.+\.vue)(?:\?[^)]*)?:(\d+):(\d+)\)/);
61
+ const urlMatch = callerLine.match(URL_MATCH_RE) || callerLine.match(URL_PAREN_MATCH_RE);
58
62
  if (urlMatch) {
59
63
  const [, filePath, line, column] = urlMatch;
60
64
  loadedFrom = `./${filePath}:${line}:${column}`;
61
65
  } else {
62
- const vueMatch = callerLine.match(/([^/\s]+\.vue):(\d+):(\d+)/);
66
+ const vueMatch = callerLine.match(VUE_MATCH_RE);
63
67
  if (vueMatch) {
64
68
  const [, fileName, line, column] = vueMatch;
65
69
  loadedFrom = `./${fileName}:${line}:${column}`;
66
70
  } else {
67
- loadedFrom = callerLine.trim().replace(/^\s*at\s+/, "");
71
+ loadedFrom = callerLine.trim().replace(CLEAN_CALLER_RE, "");
68
72
  }
69
73
  }
70
74
  }
71
75
  scriptOptions.devtools = defu(scriptOptions.devtools, { registryKey, loadedFrom });
72
76
  if (options.schema) {
73
77
  const registryMeta = {};
74
- for (const k in options.schema.entries) {
75
- if (options.schema.entries[k].type !== "optional") {
78
+ const entries = "entries" in options.schema ? options.schema.entries : void 0;
79
+ for (const k in entries) {
80
+ if (entries[k]?.type !== "optional") {
76
81
  registryMeta[k] = String(userOptions[k]);
77
82
  }
78
83
  }