@nuxt/scripts 1.0.0-beta.31 → 1.0.0-beta.32

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/dist/registry.mjs CHANGED
@@ -56,6 +56,20 @@ const LOGOS = {
56
56
  snapchatPixel: `<svg width="50" height="50" viewBox="147.353 39.286 514.631 514.631" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"><path style="fill:#FFFC00;" d="M147.553,423.021v0.023c0.308,11.424,0.403,22.914,2.33,34.268 c2.042,12.012,4.961,23.725,10.53,34.627c7.529,14.756,17.869,27.217,30.921,37.396c9.371,7.309,19.608,13.111,30.94,16.771 c16.524,5.33,33.571,7.373,50.867,7.473c10.791,0.068,21.575,0.338,32.37,0.293c78.395-0.33,156.792,0.566,235.189-0.484 c10.403-0.141,20.636-1.41,30.846-3.277c19.569-3.582,36.864-11.932,51.661-25.133c17.245-15.381,28.88-34.205,34.132-56.924 c3.437-14.85,4.297-29.916,4.444-45.035v-3.016c0-1.17-0.445-256.892-0.486-260.272c-0.115-9.285-0.799-18.5-2.54-27.636 c-2.117-11.133-5.108-21.981-10.439-32.053c-5.629-10.641-12.68-20.209-21.401-28.57c-13.359-12.81-28.775-21.869-46.722-26.661 c-16.21-4.327-32.747-5.285-49.405-5.27c-0.027-0.004-0.09-0.173-0.094-0.255H278.56c-0.005,0.086-0.008,0.172-0.014,0.255 c-9.454,0.173-18.922,0.102-28.328,1.268c-10.304,1.281-20.509,3.21-30.262,6.812c-15.362,5.682-28.709,14.532-40.11,26.347 c-12.917,13.386-22.022,28.867-26.853,46.894c-4.31,16.084-5.248,32.488-5.271,49.008"/><path style="fill:#FFFFFF;" d="M407.001,473.488c-1.068,0-2.087-0.039-2.862-0.076c-0.615,0.053-1.25,0.076-1.886,0.076 c-22.437,0-37.439-10.607-50.678-19.973c-9.489-6.703-18.438-13.031-28.922-14.775c-5.149-0.854-10.271-1.287-15.22-1.287 c-8.917,0-15.964,1.383-21.109,2.389c-3.166,0.617-5.896,1.148-8.006,1.148c-2.21,0-4.895-0.49-6.014-4.311 c-0.887-3.014-1.523-5.934-2.137-8.746c-1.536-7.027-2.65-11.316-5.281-11.723c-28.141-4.342-44.768-10.738-48.08-18.484 c-0.347-0.814-0.541-1.633-0.584-2.443c-0.129-2.309,1.501-4.334,3.777-4.711c22.348-3.68,42.219-15.492,59.064-35.119 c13.049-15.195,19.457-29.713,20.145-31.316c0.03-0.072,0.065-0.148,0.101-0.217c3.247-6.588,3.893-12.281,1.926-16.916 c-3.626-8.551-15.635-12.361-23.58-14.882c-1.976-0.625-3.845-1.217-5.334-1.808c-7.043-2.782-18.626-8.66-17.083-16.773 c1.124-5.916,8.949-10.036,15.273-10.036c1.756,0,3.312,0.308,4.622,0.923c7.146,3.348,13.575,5.045,19.104,5.045 c6.876,0,10.197-2.618,11-3.362c-0.198-3.668-0.44-7.546-0.674-11.214c0-0.004-0.005-0.048-0.005-0.048 c-1.614-25.675-3.627-57.627,4.546-75.95c24.462-54.847,76.339-59.112,91.651-59.112c0.408,0,6.674-0.062,6.674-0.062 c0.283-0.005,0.59-0.009,0.908-0.009c15.354,0,67.339,4.27,91.816,59.15c8.173,18.335,6.158,50.314,4.539,76.016l-0.076,1.23 c-0.222,3.49-0.427,6.793-0.6,9.995c0.756,0.696,3.795,3.096,9.978,3.339c5.271-0.202,11.328-1.891,17.998-5.014 c2.062-0.968,4.345-1.169,5.895-1.169c2.343,0,4.727,0.456,6.714,1.285l0.106,0.041c5.66,2.009,9.367,6.024,9.447,10.242 c0.071,3.932-2.851,9.809-17.223,15.485c-1.472,0.583-3.35,1.179-5.334,1.808c-7.952,2.524-19.951,6.332-23.577,14.878 c-1.97,4.635-1.322,10.326,1.926,16.912c0.036,0.072,0.067,0.145,0.102,0.221c1,2.344,25.205,57.535,79.209,66.432 c2.275,0.379,3.908,2.406,3.778,4.711c-0.048,0.828-0.248,1.656-0.598,2.465c-3.289,7.703-19.915,14.09-48.064,18.438 c-2.642,0.408-3.755,4.678-5.277,11.668c-0.63,2.887-1.271,5.717-2.146,8.691c-0.819,2.797-2.641,4.164-5.567,4.164h-0.441 c-1.905,0-4.604-0.346-8.008-1.012c-5.95-1.158-12.623-2.236-21.109-2.236c-4.948,0-10.069,0.434-15.224,1.287 c-10.473,1.744-19.421,8.062-28.893,14.758C444.443,462.88,429.436,473.488,407.001,473.488"/><path style="fill:#020202;" d="M408.336,124.235c14.455,0,64.231,3.883,87.688,56.472c7.724,17.317,5.744,48.686,4.156,73.885 c-0.248,3.999-0.494,7.875-0.694,11.576l-0.084,1.591l1.062,1.185c0.429,0.476,4.444,4.672,13.374,5.017l0.144,0.008l0.15-0.003 c5.904-0.225,12.554-2.059,19.776-5.442c1.064-0.498,2.48-0.741,3.978-0.741c1.707,0,3.521,0.321,5.017,0.951l0.226,0.09 c3.787,1.327,6.464,3.829,6.505,6.093c0.022,1.28-0.935,5.891-14.359,11.194c-1.312,0.518-3.039,1.069-5.041,1.7 c-8.736,2.774-21.934,6.96-26.376,17.427c-2.501,5.896-1.816,12.854,2.034,20.678c1.584,3.697,26.52,59.865,82.631,69.111 c-0.011,0.266-0.079,0.557-0.229,0.9c-0.951,2.24-6.996,9.979-44.612,15.783c-5.886,0.902-7.328,7.5-9,15.17 c-0.604,2.746-1.218,5.518-2.062,8.381c-0.258,0.865-0.306,0.914-1.233,0.914c-0.128,0-0.278,0-0.442,0 c-1.668,0-4.2-0.346-7.135-0.922c-5.345-1.041-12.647-2.318-21.982-2.318c-5.21,0-10.577,0.453-15.962,1.352 c-11.511,1.914-20.872,8.535-30.786,15.543c-13.314,9.408-27.075,19.143-48.071,19.143c-0.917,0-1.812-0.031-2.709-0.076 l-0.236-0.01l-0.237,0.018c-0.515,0.045-1.034,0.068-1.564,0.068c-20.993,0-34.76-9.732-48.068-19.143 c-9.916-7.008-19.282-13.629-30.791-15.543c-5.38-0.896-10.752-1.352-15.959-1.352c-9.333,0-16.644,1.428-21.978,2.471 c-2.935,0.574-5.476,1.066-7.139,1.066c-1.362,0-1.388-0.08-1.676-1.064c-0.844-2.865-1.461-5.703-2.062-8.445 c-1.676-7.678-3.119-14.312-9.002-15.215c-37.613-5.809-43.659-13.561-44.613-15.795c-0.149-0.352-0.216-0.652-0.231-0.918 c56.11-9.238,81.041-65.408,82.63-69.119c3.857-7.818,4.541-14.775,2.032-20.678c-4.442-10.461-17.638-14.653-26.368-17.422 c-2.007-0.635-3.735-1.187-5.048-1.705c-11.336-4.479-14.823-8.991-14.305-11.725c0.601-3.153,6.067-6.359,10.837-6.359 c1.072,0,2.012,0.173,2.707,0.498c7.747,3.631,14.819,5.472,21.022,5.472c9.751,0,14.091-4.537,14.557-5.055l1.057-1.182 l-0.085-1.583c-0.197-3.699-0.44-7.574-0.696-11.565c-1.583-25.205-3.563-56.553,4.158-73.871 c23.37-52.396,72.903-56.435,87.525-56.435c0.36,0,6.717-0.065,6.717-0.065C407.744,124.239,408.033,124.235,408.336,124.235 M408.336,115.197h-0.017c-0.333,0-0.646,0-0.944,0.004c-2.376,0.024-6.282,0.062-6.633,0.066c-8.566,0-25.705,1.21-44.115,9.336 c-10.526,4.643-19.994,10.921-28.14,18.66c-9.712,9.221-17.624,20.59-23.512,33.796c-8.623,19.336-6.576,51.905-4.932,78.078 l0.006,0.041c0.176,2.803,0.361,5.73,0.53,8.582c-1.265,0.581-3.316,1.194-6.339,1.194c-4.864,0-10.648-1.555-17.187-4.619 c-1.924-0.896-4.12-1.349-6.543-1.349c-3.893,0-7.997,1.146-11.557,3.239c-4.479,2.63-7.373,6.347-8.159,10.468 c-0.518,2.726-0.493,8.114,5.492,13.578c3.292,3.008,8.128,5.782,14.37,8.249c1.638,0.645,3.582,1.261,5.641,1.914 c7.145,2.271,17.959,5.702,20.779,12.339c1.429,3.365,0.814,7.793-1.823,13.145c-0.069,0.146-0.138,0.289-0.201,0.439 c-0.659,1.539-6.807,15.465-19.418,30.152c-7.166,8.352-15.059,15.332-23.447,20.752c-10.238,6.617-21.316,10.943-32.923,12.855 c-4.558,0.748-7.813,4.809-7.559,9.424c0.078,1.33,0.39,2.656,0.931,3.939c0.004,0.008,0.009,0.016,0.013,0.023 c1.843,4.311,6.116,7.973,13.063,11.203c8.489,3.943,21.185,7.26,37.732,9.855c0.836,1.59,1.704,5.586,2.305,8.322 c0.629,2.908,1.285,5.898,2.22,9.074c1.009,3.441,3.626,7.553,10.349,7.553c2.548,0,5.478-0.574,8.871-1.232 c4.969-0.975,11.764-2.305,20.245-2.305c4.702,0,9.575,0.414,14.48,1.229c9.455,1.574,17.606,7.332,27.037,14 c13.804,9.758,29.429,20.803,53.302,20.803c0.651,0,1.304-0.021,1.949-0.066c0.789,0.037,1.767,0.066,2.799,0.066 c23.88,0,39.501-11.049,53.29-20.799l0.022-0.02c9.433-6.66,17.575-12.41,27.027-13.984c4.903-0.814,9.775-1.229,14.479-1.229 c8.102,0,14.517,1.033,20.245,2.15c3.738,0.736,6.643,1.09,8.872,1.09l0.218,0.004h0.226c4.917,0,8.53-2.699,9.909-7.422 c0.916-3.109,1.57-6.029,2.215-8.986c0.562-2.564,1.46-6.674,2.296-8.281c16.558-2.6,29.249-5.91,37.739-9.852 c6.931-3.215,11.199-6.873,13.053-11.166c0.556-1.287,0.881-2.621,0.954-3.979c0.261-4.607-2.999-8.676-7.56-9.424 c-51.585-8.502-74.824-61.506-75.785-63.758c-0.062-0.148-0.132-0.295-0.205-0.438c-2.637-5.354-3.246-9.777-1.816-13.148 c2.814-6.631,13.621-10.062,20.771-12.332c2.07-0.652,4.021-1.272,5.646-1.914c7.039-2.78,12.07-5.796,15.389-9.221 c3.964-4.083,4.736-7.995,4.688-10.555c-0.121-6.194-4.856-11.698-12.388-14.393c-2.544-1.052-5.445-1.607-8.399-1.607 c-2.011,0-4.989,0.276-7.808,1.592c-6.035,2.824-11.441,4.368-16.082,4.588c-2.468-0.125-4.199-0.66-5.32-1.171 c0.141-2.416,0.297-4.898,0.458-7.486l0.067-1.108c1.653-26.19,3.707-58.784-4.92-78.134c-5.913-13.253-13.853-24.651-23.604-33.892 c-8.178-7.744-17.678-14.021-28.242-18.661C434.052,116.402,416.914,115.197,408.336,115.197"/><rect x="147.553" y="39.443" style="fill:none;" width="514.231" height="514.23"/></svg>`
57
57
  };
58
58
 
59
+ const PRIVACY_NONE = { ip: false, userAgent: false, language: false, screen: false, timezone: false, hardware: false };
60
+ const PRIVACY_FULL = { ip: true, userAgent: true, language: true, screen: true, timezone: true, hardware: true };
61
+ const PRIVACY_HEATMAP = { ip: true, userAgent: false, language: true, screen: false, timezone: false, hardware: true };
62
+ const PRIVACY_IP_ONLY = { ip: true, userAgent: false, language: false, screen: false, timezone: false, hardware: false };
63
+ const FATHOM_SELF_HOSTED_RE = /\.src\.indexOf\("cdn\.usefathom\.com"\)\s*<\s*0/;
64
+ const RYBBIT_HOST_SPLIT_RE = /\w+\.split\(["']\/script\.js["']\)\[0\]/g;
65
+ const CAP_FULL_PT = { bundle: true, reverseProxyIntercept: true, partytown: true };
66
+ const CAP_FULL = { bundle: true, reverseProxyIntercept: true };
67
+ const CAP_BUNDLE_PT = { bundle: true, partytown: true };
68
+ const CAP_BUNDLE = { bundle: true };
69
+ const CAP_PROXY = { reverseProxyIntercept: true };
70
+ const DEF_FULL = { bundle: true, reverseProxyIntercept: true };
71
+ const DEF_BUNDLE = { bundle: true };
72
+ const DEF_PROXY = { reverseProxyIntercept: true };
59
73
  async function registry(resolve) {
60
74
  resolve = resolve || ((s) => Promise.resolve(s));
61
75
  return [
@@ -63,6 +77,11 @@ async function registry(resolve) {
63
77
  registryKey: "plausibleAnalytics",
64
78
  label: "Plausible Analytics",
65
79
  category: "analytics",
80
+ capabilities: CAP_FULL_PT,
81
+ defaultCapability: DEF_FULL,
82
+ domains: ["plausible.io"],
83
+ privacy: PRIVACY_NONE,
84
+ autoInject: { configField: "endpoint", computeValue: (proxyPrefix) => `${proxyPrefix}/plausible.io/api/event` },
66
85
  scriptBundling: (options) => {
67
86
  if (options?.scriptId)
68
87
  return `https://plausible.io/js/pa-${options.scriptId}.js`;
@@ -80,6 +99,10 @@ async function registry(resolve) {
80
99
  label: "Cloudflare Web Analytics",
81
100
  src: "https://static.cloudflareinsights.com/beacon.min.js",
82
101
  category: "analytics",
102
+ capabilities: CAP_FULL_PT,
103
+ defaultCapability: DEF_FULL,
104
+ domains: ["static.cloudflareinsights.com", "cloudflareinsights.com"],
105
+ privacy: PRIVACY_NONE,
83
106
  logo: LOGOS.cloudflareWebAnalytics,
84
107
  import: {
85
108
  name: "useScriptCloudflareWebAnalytics",
@@ -91,6 +114,10 @@ async function registry(resolve) {
91
114
  label: "Vercel Analytics",
92
115
  src: "https://va.vercel-scripts.com/v1/script.js",
93
116
  category: "analytics",
117
+ capabilities: CAP_FULL,
118
+ defaultCapability: DEF_FULL,
119
+ domains: ["va.vercel-scripts.com"],
120
+ privacy: PRIVACY_NONE,
94
121
  logo: LOGOS.vercelAnalytics,
95
122
  import: {
96
123
  name: "useScriptVercelAnalytics",
@@ -102,6 +129,18 @@ async function registry(resolve) {
102
129
  label: "PostHog",
103
130
  src: false,
104
131
  scriptBundling: false,
132
+ capabilities: CAP_PROXY,
133
+ defaultCapability: DEF_PROXY,
134
+ domains: ["us-assets.i.posthog.com", "us.i.posthog.com", "eu-assets.i.posthog.com", "eu.i.posthog.com"],
135
+ privacy: PRIVACY_NONE,
136
+ autoInject: {
137
+ configField: "apiHost",
138
+ computeValue: (proxyPrefix, config) => {
139
+ const region = config.region || "us";
140
+ const host = region === "eu" ? "eu.i.posthog.com" : "us.i.posthog.com";
141
+ return `${proxyPrefix}/${host}`;
142
+ }
143
+ },
105
144
  category: "analytics",
106
145
  logo: LOGOS.posthog,
107
146
  import: {
@@ -114,6 +153,13 @@ async function registry(resolve) {
114
153
  label: "Fathom Analytics",
115
154
  src: "https://cdn.usefathom.com/script.js",
116
155
  category: "analytics",
156
+ capabilities: CAP_FULL_PT,
157
+ defaultCapability: DEF_FULL,
158
+ domains: ["cdn.usefathom.com"],
159
+ privacy: PRIVACY_NONE,
160
+ postProcess(output) {
161
+ return output.replace(FATHOM_SELF_HOSTED_RE, '.src.indexOf("cdn.usefathom.com")<-1');
162
+ },
117
163
  logo: LOGOS.fathomAnalytics,
118
164
  import: {
119
165
  name: "useScriptFathomAnalytics",
@@ -125,6 +171,10 @@ async function registry(resolve) {
125
171
  label: "Matomo Analytics",
126
172
  scriptBundling: false,
127
173
  // breaks script
174
+ capabilities: CAP_FULL_PT,
175
+ defaultCapability: DEF_FULL,
176
+ domains: ["cdn.matomo.cloud"],
177
+ privacy: PRIVACY_NONE,
128
178
  category: "analytics",
129
179
  logo: LOGOS.matomoAnalytics,
130
180
  import: {
@@ -135,6 +185,17 @@ async function registry(resolve) {
135
185
  {
136
186
  registryKey: "rybbitAnalytics",
137
187
  label: "Rybbit Analytics",
188
+ capabilities: CAP_FULL,
189
+ defaultCapability: DEF_FULL,
190
+ domains: ["app.rybbit.io"],
191
+ privacy: PRIVACY_NONE,
192
+ autoInject: { configField: "analyticsHost", computeValue: (proxyPrefix) => `${proxyPrefix}/app.rybbit.io/api` },
193
+ postProcess(output, rewrites) {
194
+ const rybbitRewrite = rewrites.find((r) => r.from === "app.rybbit.io");
195
+ if (rybbitRewrite)
196
+ output = output.replace(RYBBIT_HOST_SPLIT_RE, `self.location.origin+"${rybbitRewrite.to}/api"`);
197
+ return output;
198
+ },
138
199
  scriptBundling: (options) => {
139
200
  const host = options?.analyticsHost;
140
201
  if (host && !host.startsWith("/"))
@@ -151,6 +212,11 @@ async function registry(resolve) {
151
212
  {
152
213
  registryKey: "databuddyAnalytics",
153
214
  label: "Databuddy Analytics",
215
+ capabilities: CAP_FULL,
216
+ defaultCapability: DEF_FULL,
217
+ domains: ["cdn.databuddy.cc", "basket.databuddy.cc"],
218
+ privacy: PRIVACY_NONE,
219
+ autoInject: { configField: "apiUrl", computeValue: (proxyPrefix) => `${proxyPrefix}/basket.databuddy.cc` },
154
220
  scriptBundling: () => "https://cdn.databuddy.cc/databuddy.js",
155
221
  category: "analytics",
156
222
  logo: LOGOS.databuddyAnalytics,
@@ -162,6 +228,9 @@ async function registry(resolve) {
162
228
  {
163
229
  registryKey: "segment",
164
230
  label: "Segment",
231
+ capabilities: CAP_BUNDLE_PT,
232
+ // reverseProxyIntercept fails: SDK constructs API URLs dynamically
233
+ defaultCapability: DEF_BUNDLE,
165
234
  scriptBundling: (options) => {
166
235
  return joinURL("https://cdn.segment.com/analytics.js/v1", options?.writeKey || "", "analytics.min.js");
167
236
  },
@@ -175,6 +244,8 @@ async function registry(resolve) {
175
244
  {
176
245
  registryKey: "mixpanelAnalytics",
177
246
  label: "Mixpanel",
247
+ capabilities: CAP_BUNDLE_PT,
248
+ defaultCapability: DEF_BUNDLE,
178
249
  scriptBundling: (options) => {
179
250
  if (!options?.token)
180
251
  return false;
@@ -191,6 +262,8 @@ async function registry(resolve) {
191
262
  registryKey: "bingUet",
192
263
  label: "Bing UET",
193
264
  src: "https://bat.bing.com/bat.js",
265
+ capabilities: CAP_BUNDLE_PT,
266
+ defaultCapability: DEF_BUNDLE,
194
267
  category: "ad",
195
268
  logo: LOGOS.bingUet,
196
269
  import: {
@@ -203,6 +276,10 @@ async function registry(resolve) {
203
276
  label: "Meta Pixel",
204
277
  src: "https://connect.facebook.net/en_US/fbevents.js",
205
278
  category: "ad",
279
+ capabilities: CAP_FULL_PT,
280
+ defaultCapability: DEF_FULL,
281
+ domains: ["connect.facebook.net", "www.facebook.com", "facebook.com", "pixel.facebook.com"],
282
+ privacy: PRIVACY_FULL,
206
283
  logo: LOGOS.metaPixel,
207
284
  import: {
208
285
  name: "useScriptMetaPixel",
@@ -214,6 +291,10 @@ async function registry(resolve) {
214
291
  label: "X Pixel",
215
292
  src: "https://static.ads-twitter.com/uwt.js",
216
293
  category: "ad",
294
+ capabilities: CAP_FULL_PT,
295
+ defaultCapability: DEF_FULL,
296
+ domains: ["analytics.twitter.com", "static.ads-twitter.com", "t.co"],
297
+ privacy: PRIVACY_FULL,
217
298
  logo: LOGOS.xPixel,
218
299
  import: {
219
300
  name: "useScriptXPixel",
@@ -224,6 +305,10 @@ async function registry(resolve) {
224
305
  registryKey: "tiktokPixel",
225
306
  label: "TikTok Pixel",
226
307
  category: "ad",
308
+ capabilities: CAP_FULL_PT,
309
+ defaultCapability: DEF_FULL,
310
+ domains: ["analytics.tiktok.com"],
311
+ privacy: PRIVACY_FULL,
227
312
  logo: LOGOS.tiktokPixel,
228
313
  import: {
229
314
  name: "useScriptTikTokPixel",
@@ -240,6 +325,10 @@ async function registry(resolve) {
240
325
  label: "Snapchat Pixel",
241
326
  src: "https://sc-static.net/scevent.min.js",
242
327
  category: "ad",
328
+ capabilities: CAP_FULL_PT,
329
+ defaultCapability: DEF_FULL,
330
+ domains: ["sc-static.net", "tr.snapchat.com", "pixel.tapad.com"],
331
+ privacy: PRIVACY_FULL,
243
332
  logo: LOGOS.snapchatPixel,
244
333
  import: {
245
334
  name: "useScriptSnapchatPixel",
@@ -251,6 +340,10 @@ async function registry(resolve) {
251
340
  label: "Reddit Pixel",
252
341
  src: "https://www.redditstatic.com/ads/pixel.js",
253
342
  category: "ad",
343
+ capabilities: CAP_FULL_PT,
344
+ defaultCapability: DEF_FULL,
345
+ domains: ["www.redditstatic.com", "alb.reddit.com", "pixel-config.reddit.com"],
346
+ privacy: PRIVACY_FULL,
254
347
  logo: LOGOS.redditPixel,
255
348
  import: {
256
349
  name: "useScriptRedditPixel",
@@ -261,7 +354,10 @@ async function registry(resolve) {
261
354
  {
262
355
  registryKey: "googleAdsense",
263
356
  label: "Google Adsense",
264
- proxy: "googleAnalytics",
357
+ capabilities: CAP_FULL,
358
+ defaultCapability: DEF_FULL,
359
+ proxyConfig: "googleAnalytics",
360
+ // shares GA's domains/privacy
265
361
  scriptBundling: (options) => {
266
362
  if (!options?.client) {
267
363
  return false;
@@ -281,6 +377,10 @@ async function registry(resolve) {
281
377
  registryKey: "carbonAds",
282
378
  label: "Carbon Ads",
283
379
  scriptBundling: false,
380
+ capabilities: CAP_FULL,
381
+ defaultCapability: DEF_FULL,
382
+ domains: ["cdn.carbonads.com"],
383
+ privacy: PRIVACY_NONE,
284
384
  category: "ad",
285
385
  logo: LOGOS.carbonAds
286
386
  },
@@ -288,6 +388,10 @@ async function registry(resolve) {
288
388
  {
289
389
  registryKey: "intercom",
290
390
  label: "Intercom",
391
+ capabilities: CAP_FULL,
392
+ defaultCapability: DEF_FULL,
393
+ domains: ["widget.intercom.io", "api-iam.intercom.io", "api-iam.eu.intercom.io", "api-iam.au.intercom.io", "js.intercomcdn.com", "downloads.intercomcdn.com", "video-messages.intercomcdn.com"],
394
+ privacy: PRIVACY_IP_ONLY,
291
395
  scriptBundling(options) {
292
396
  if (!options?.app_id) {
293
397
  return false;
@@ -304,6 +408,10 @@ async function registry(resolve) {
304
408
  {
305
409
  registryKey: "hotjar",
306
410
  label: "Hotjar",
411
+ capabilities: CAP_FULL,
412
+ defaultCapability: DEF_FULL,
413
+ domains: ["static.hotjar.com", "script.hotjar.com", "vars.hotjar.com", "in.hotjar.com", "vc.hotjar.com", "vc.hotjar.io", "metrics.hotjar.io", "insights.hotjar.com", "ask.hotjar.io", "events.hotjar.io", "identify.hotjar.com", "surveystats.hotjar.io"],
414
+ privacy: PRIVACY_HEATMAP,
307
415
  scriptBundling(options) {
308
416
  if (!options?.id) {
309
417
  return false;
@@ -322,6 +430,10 @@ async function registry(resolve) {
322
430
  {
323
431
  registryKey: "clarity",
324
432
  label: "Clarity",
433
+ capabilities: CAP_FULL_PT,
434
+ defaultCapability: DEF_FULL,
435
+ domains: ["www.clarity.ms", "scripts.clarity.ms", "d.clarity.ms", "e.clarity.ms", "k.clarity.ms"],
436
+ privacy: PRIVACY_HEATMAP,
325
437
  scriptBundling(options) {
326
438
  if (!options?.id) {
327
439
  return false;
@@ -341,7 +453,6 @@ async function registry(resolve) {
341
453
  label: "Stripe",
342
454
  scriptBundling: false,
343
455
  // needs fingerprinting for fraud detection
344
- proxy: false,
345
456
  category: "payments",
346
457
  logo: LOGOS.stripe,
347
458
  import: {
@@ -354,6 +465,10 @@ async function registry(resolve) {
354
465
  label: "Lemon Squeezy",
355
466
  src: false,
356
467
  // should not be bundled
468
+ capabilities: CAP_FULL,
469
+ defaultCapability: DEF_FULL,
470
+ domains: ["assets.lemonsqueezy.com"],
471
+ privacy: PRIVACY_NONE,
357
472
  category: "payments",
358
473
  logo: LOGOS.lemonSqueezy,
359
474
  import: {
@@ -366,7 +481,6 @@ async function registry(resolve) {
366
481
  label: "PayPal",
367
482
  src: false,
368
483
  // needs fingerprinting for fraud detection
369
- proxy: false,
370
484
  category: "payments",
371
485
  logo: LOGOS.paypal,
372
486
  import: {
@@ -378,6 +492,10 @@ async function registry(resolve) {
378
492
  {
379
493
  registryKey: "vimeoPlayer",
380
494
  label: "Vimeo Player",
495
+ capabilities: CAP_FULL,
496
+ defaultCapability: DEF_FULL,
497
+ domains: ["player.vimeo.com"],
498
+ privacy: PRIVACY_IP_ONLY,
381
499
  category: "video",
382
500
  logo: LOGOS.vimeoPlayer,
383
501
  import: {
@@ -388,6 +506,10 @@ async function registry(resolve) {
388
506
  {
389
507
  registryKey: "youtubePlayer",
390
508
  label: "YouTube Player",
509
+ capabilities: CAP_FULL,
510
+ defaultCapability: DEF_FULL,
511
+ domains: ["www.youtube.com"],
512
+ privacy: PRIVACY_IP_ONLY,
391
513
  category: "video",
392
514
  logo: LOGOS.youtubePlayer,
393
515
  import: {
@@ -444,6 +566,9 @@ async function registry(resolve) {
444
566
  {
445
567
  registryKey: "crisp",
446
568
  label: "Crisp",
569
+ capabilities: CAP_BUNDLE,
570
+ // reverseProxyIntercept fails: SDK loads secondary scripts at runtime
571
+ defaultCapability: DEF_BUNDLE,
447
572
  category: "support",
448
573
  logo: LOGOS.crisp,
449
574
  import: {
@@ -471,7 +596,6 @@ async function registry(resolve) {
471
596
  label: "Google reCAPTCHA",
472
597
  scriptBundling: false,
473
598
  // needs fingerprinting for bot detection
474
- proxy: false,
475
599
  category: "utility",
476
600
  logo: LOGOS.googleRecaptcha,
477
601
  import: {
@@ -485,7 +609,6 @@ async function registry(resolve) {
485
609
  src: "https://accounts.google.com/gsi/client",
486
610
  scriptBundling: false,
487
611
  // CORS prevents bundling, needs fingerprinting for auth
488
- proxy: false,
489
612
  category: "utility",
490
613
  logo: LOGOS.googleSignIn,
491
614
  import: {
@@ -496,6 +619,9 @@ async function registry(resolve) {
496
619
  {
497
620
  registryKey: "googleTagManager",
498
621
  label: "Google Tag Manager",
622
+ capabilities: CAP_BUNDLE,
623
+ // reverseProxyIntercept fails: GTM dynamically loads scripts at runtime
624
+ defaultCapability: DEF_BUNDLE,
499
625
  category: "tag-manager",
500
626
  import: {
501
627
  name: "useScriptGoogleTagManager",
@@ -523,6 +649,10 @@ async function registry(resolve) {
523
649
  {
524
650
  registryKey: "googleAnalytics",
525
651
  label: "Google Analytics",
652
+ capabilities: CAP_FULL_PT,
653
+ defaultCapability: DEF_FULL,
654
+ domains: ["www.google-analytics.com", "analytics.google.com", "stats.g.doubleclick.net", "pagead2.googlesyndication.com", "www.googleadservices.com", "googleads.g.doubleclick.net"],
655
+ privacy: PRIVACY_HEATMAP,
526
656
  category: "analytics",
527
657
  import: {
528
658
  name: "useScriptGoogleAnalytics",
@@ -539,6 +669,11 @@ async function registry(resolve) {
539
669
  {
540
670
  registryKey: "umamiAnalytics",
541
671
  label: "Umami Analytics",
672
+ capabilities: CAP_FULL_PT,
673
+ defaultCapability: DEF_FULL,
674
+ domains: ["cloud.umami.is", "api-gateway.umami.dev"],
675
+ privacy: PRIVACY_NONE,
676
+ autoInject: { configField: "hostUrl", computeValue: (proxyPrefix) => `${proxyPrefix}/cloud.umami.is` },
542
677
  scriptBundling: () => "https://cloud.umami.is/script.js",
543
678
  category: "analytics",
544
679
  logo: LOGOS.umamiAnalytics,
@@ -551,6 +686,10 @@ async function registry(resolve) {
551
686
  registryKey: "gravatar",
552
687
  label: "Gravatar",
553
688
  src: "https://secure.gravatar.com/js/gprofiles.js",
689
+ capabilities: CAP_FULL,
690
+ defaultCapability: DEF_FULL,
691
+ domains: ["secure.gravatar.com", "gravatar.com"],
692
+ privacy: PRIVACY_IP_ONLY,
554
693
  category: "utility",
555
694
  logo: LOGOS.gravatar,
556
695
  import: {
@@ -564,4 +703,4 @@ async function registry(resolve) {
564
703
  ];
565
704
  }
566
705
 
567
- export { registry };
706
+ export { PRIVACY_FULL, PRIVACY_HEATMAP, PRIVACY_IP_ONLY, PRIVACY_NONE, registry };
@@ -5,7 +5,7 @@ export type GravatarInput = RegistryScriptInput<typeof GravatarOptions>;
5
5
  export interface GravatarApi {
6
6
  /**
7
7
  * Get a proxied avatar URL for a given SHA256 email hash.
8
- * When firstParty mode is enabled, this routes through your server.
8
+ * When proxy mode is enabled, this routes through your server.
9
9
  */
10
10
  getAvatarUrl: (hash: string, options?: {
11
11
  size?: number;
@@ -250,7 +250,6 @@ export default defineEventHandler(async (event) => {
250
250
  duplex: passthroughBody ? "half" : void 0
251
251
  });
252
252
  } catch (err) {
253
- clearTimeout(timeoutId);
254
253
  log("[proxy] Upstream error:", err);
255
254
  throw createError({
256
255
  statusCode: 502,
@@ -129,12 +129,4 @@ export declare function generalizeTimezone(value: unknown): string | number;
129
129
  * (timezone, language, screen dimensions) while keeping low-entropy values.
130
130
  */
131
131
  export declare function anonymizeDeviceInfo(value: string): string;
132
- /**
133
- * Recursively anonymize fingerprinting data in payload.
134
- * Fields are generalized or normalized rather than stripped, so endpoints
135
- * still receive valid data with reduced fingerprinting precision.
136
- *
137
- * When `privacy` is provided, only categories with their flag set to `true` are processed.
138
- * Default (no arg) = all categories active, so existing callers work unchanged.
139
- */
140
132
  export declare function stripPayloadFingerprinting(payload: Record<string, unknown>, privacy?: ResolvedProxyPrivacy): Record<string, unknown>;
@@ -232,6 +232,13 @@ export function anonymizeDeviceInfo(value) {
232
232
  }
233
233
  return result.join(sep);
234
234
  }
235
+ function matchesParam(key, params) {
236
+ const lk = key.toLowerCase();
237
+ return params.some((pm) => {
238
+ const lp = pm.toLowerCase();
239
+ return lk === lp || lk.startsWith(`${lp}[`);
240
+ });
241
+ }
235
242
  export function stripPayloadFingerprinting(payload, privacy) {
236
243
  const p = privacy || FULL_PRIVACY;
237
244
  const result = {};
@@ -245,13 +252,6 @@ export function stripPayloadFingerprinting(payload, privacy) {
245
252
  }
246
253
  for (const [key, value] of Object.entries(payload)) {
247
254
  const lowerKey = key.toLowerCase();
248
- const matchesParam = (key2, params) => {
249
- const lk = key2.toLowerCase();
250
- return params.some((pm) => {
251
- const lp = pm.toLowerCase();
252
- return lk === lp || lk.startsWith(`${lp}[`);
253
- });
254
- };
255
255
  const isLanguageParam = NORMALIZE_PARAMS.language.some((pm) => lowerKey === pm.toLowerCase());
256
256
  if (isLanguageParam) {
257
257
  if (Array.isArray(value)) {
@@ -66,16 +66,16 @@ export type NuxtUseScriptOptions<T extends Record<symbol | string, any> = {}> =
66
66
  *
67
67
  * Note: Using 'force' may significantly increase build time as scripts will be re-downloaded on every build.
68
68
  *
69
- * @deprecated Use `scripts.firstParty: true` in nuxt.config instead for bundling and routing scripts through your domain.
69
+ * @deprecated Bundling is now auto-enabled per-script via capabilities. Set `bundle: false` per-script to disable.
70
70
  */
71
71
  bundle?: boolean | 'force';
72
72
  /**
73
- * Opt-out of first-party routing for this specific script when global `scripts.firstParty` is enabled.
74
- * Set to `false` to load this script directly from its original source instead of through your domain.
75
- *
76
- * Note: This option only works as an opt-out. To enable first-party routing, use the global `scripts.firstParty` option in nuxt.config.
73
+ * Control reverse proxy interception for this script.
74
+ * When `false`, collection requests go directly to the third-party server.
75
+ * When `true`, collection requests are proxied through `/_scripts/p/`.
76
+ * Defaults to the script's `defaultCapability.reverseProxyIntercept` from the registry.
77
77
  */
78
- firstParty?: false;
78
+ reverseProxyIntercept?: boolean;
79
79
  /**
80
80
  * Load the script in a web worker using Partytown.
81
81
  * When enabled, adds `type="text/partytown"` to the script tag.
@@ -235,6 +235,36 @@ export interface RegistryScriptServerHandler {
235
235
  handler: string;
236
236
  middleware?: boolean;
237
237
  }
238
+ /**
239
+ * Declares what optimization modes a script supports and what's active by default.
240
+ * Each flag is an independent capability that must be explicitly opted into.
241
+ */
242
+ export interface ScriptCapabilities {
243
+ /** Script can be downloaded at build time and served from `/_scripts/assets/`. */
244
+ bundle?: boolean;
245
+ /**
246
+ * Collection requests can be proxied through `/_scripts/p/`.
247
+ * When combined with `bundle`: AST URL rewriting + runtime intercept.
248
+ * Without `bundle` (npm mode): autoInject sets SDK endpoint to proxy URL.
249
+ */
250
+ reverseProxyIntercept?: boolean;
251
+ /** Script can run in a web worker via Partytown. */
252
+ partytown?: boolean;
253
+ }
254
+ /**
255
+ * A third-party domain the script communicates with.
256
+ * Used for proxy routing, AST rewriting, and connection warming (dns-prefetch/preconnect).
257
+ */
258
+ export interface ScriptDomain {
259
+ /** The domain hostname (e.g., 'www.google-analytics.com') */
260
+ domain: string;
261
+ /**
262
+ * Whether this domain is used lazily (e.g., only after user interaction or SDK initialization).
263
+ * When `true`, connection warming uses `dns-prefetch` instead of `preconnect`.
264
+ * @default false
265
+ */
266
+ lazy?: boolean;
267
+ }
238
268
  export interface RegistryScript {
239
269
  /**
240
270
  * The config key used in `scripts.registry` in nuxt.config (e.g., 'googleAnalytics', 'plausibleAnalytics').
@@ -244,14 +274,42 @@ export interface RegistryScript {
244
274
  import?: Import;
245
275
  scriptBundling?: false | ((options?: any) => string | false);
246
276
  /**
247
- * First-party proxy config alias. Only needed when a script shares another script's
248
- * proxy config (e.g., googleAdsense uses `proxy: 'googleAnalytics'`).
249
- *
250
- * By default, the proxy config is looked up by `registryKey`. Set to `false` to
251
- * explicitly disable first-party routing for this script.
252
- * @internal
277
+ * What optimization modes this script supports (the ceiling).
278
+ * Each capability must be explicitly opted in. Omitted flags default to false.
279
+ */
280
+ capabilities?: ScriptCapabilities;
281
+ /**
282
+ * What capabilities are active by default for users (subset of capabilities).
283
+ * Users inherit these and can toggle individual flags via scriptOptions.
284
+ * Omitted flags are not active by default (e.g., partytown requires user opt-in).
285
+ */
286
+ defaultCapability?: ScriptCapabilities;
287
+ /**
288
+ * Third-party domains this script communicates with.
289
+ * Used for: proxy routing, AST URL rewriting, connection warming (dns-prefetch/preconnect).
290
+ * Domains marked `lazy: true` use dns-prefetch; others use preconnect for immediate scripts.
291
+ */
292
+ domains?: (string | ScriptDomain)[];
293
+ /**
294
+ * Privacy controls for proxied requests to this script's domains.
295
+ * Only relevant when reverseProxyIntercept capability is active.
296
+ */
297
+ privacy?: import('../runtime/server/utils/privacy').ProxyPrivacyInput;
298
+ /**
299
+ * Auto-inject proxy endpoint config into the script's SDK options.
300
+ * For scripts that let you configure the collection endpoint (PostHog, Plausible, etc.).
301
+ */
302
+ autoInject?: import('../first-party/types').ProxyAutoInject;
303
+ /**
304
+ * SDK-specific post-processing applied after AST URL rewriting.
305
+ * Used for regex patches that can't be handled by the generic AST rewriter.
306
+ */
307
+ postProcess?: (output: string, rewrites: import('../runtime/utils/pure').ProxyRewrite[]) => string;
308
+ /**
309
+ * Proxy config alias. When set, inherits domains/privacy/autoInject/postProcess
310
+ * from another script (e.g., googleAdsense → 'googleAnalytics').
253
311
  */
254
- proxy?: RegistryScriptKey | false;
312
+ proxyConfig?: RegistryScriptKey;
255
313
  label?: string;
256
314
  src?: string | false;
257
315
  category?: string;
@@ -0,0 +1,37 @@
1
+ function buildProxyConfigsFromRegistry(scripts) {
2
+ const configs = {};
3
+ const scriptByKey = /* @__PURE__ */ new Map();
4
+ for (const script of scripts) {
5
+ if (script.registryKey)
6
+ scriptByKey.set(script.registryKey, script);
7
+ }
8
+ for (const script of scripts) {
9
+ if (!script.registryKey || !script.capabilities?.reverseProxyIntercept)
10
+ continue;
11
+ if (script.proxyConfig) {
12
+ const source = scriptByKey.get(script.proxyConfig);
13
+ if (source?.domains) {
14
+ const domains2 = source.domains.map((d) => typeof d === "string" ? d : d.domain);
15
+ configs[script.registryKey] = {
16
+ domains: domains2,
17
+ privacy: source.privacy || { ip: false, userAgent: false, language: false, screen: false, timezone: false, hardware: false },
18
+ autoInject: source.autoInject,
19
+ postProcess: source.postProcess
20
+ };
21
+ }
22
+ continue;
23
+ }
24
+ if (!script.domains?.length)
25
+ continue;
26
+ const domains = script.domains.map((d) => typeof d === "string" ? d : d.domain);
27
+ configs[script.registryKey] = {
28
+ domains,
29
+ privacy: script.privacy || { ip: false, userAgent: false, language: false, screen: false, timezone: false, hardware: false },
30
+ autoInject: script.autoInject,
31
+ postProcess: script.postProcess
32
+ };
33
+ }
34
+ return configs;
35
+ }
36
+
37
+ export { buildProxyConfigsFromRegistry as b };
package/dist/stats.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { g as getAllProxyConfigs } from './shared/scripts.D7e2ENu6.mjs';
1
+ import { b as buildProxyConfigsFromRegistry } from './shared/scripts.T4Z99VT8.mjs';
2
2
 
3
3
  const scriptMeta = {
4
4
  // Analytics
@@ -3798,13 +3798,13 @@ function deriveMetaKey(importName, label) {
3798
3798
  async function getScriptStats() {
3799
3799
  const { registry } = await import('./registry.mjs');
3800
3800
  const entries = await registry();
3801
- const proxyConfigs = getAllProxyConfigs();
3801
+ const proxyConfigs = buildProxyConfigsFromRegistry(entries);
3802
3802
  const sizes = scriptSizes;
3803
3803
  return entries.map((entry) => {
3804
3804
  const id = entry.registryKey || deriveMetaKey(entry.import?.name, entry.label);
3805
3805
  const meta = id && id in scriptMeta ? scriptMeta[id] : void 0;
3806
3806
  const size = sizes[id || ""];
3807
- const proxyConfigKey = entry.proxy === false ? void 0 : entry.proxy || entry.registryKey;
3807
+ const proxyConfigKey = !entry.capabilities?.reverseProxyIntercept ? void 0 : entry.proxyConfig || entry.registryKey;
3808
3808
  const proxyConfig = proxyConfigKey ? proxyConfigs[proxyConfigKey] : void 0;
3809
3809
  let loadingMethod = "cdn";
3810
3810
  if (entry.src === false)
@@ -429,7 +429,7 @@ const types = {
429
429
  {
430
430
  name: "GravatarApi",
431
431
  kind: "interface",
432
- code: "export interface GravatarApi {\n /**\n * Get a proxied avatar URL for a given SHA256 email hash.\n * When firstParty mode is enabled, this routes through your server.\n */\n getAvatarUrl: (hash: string, options?: { size?: number, default?: string, rating?: string }) => string\n /**\n * Get a proxied avatar URL using the server-side hashing endpoint.\n * The email is sent to YOUR server (not Gravatar) for hashing.\n * Only available when the gravatar proxy is enabled.\n */\n getAvatarUrlFromEmail: (email: string, options?: { size?: number, default?: string, rating?: string }) => string\n}"
432
+ code: "export interface GravatarApi {\n /**\n * Get a proxied avatar URL for a given SHA256 email hash.\n * When proxy mode is enabled, this routes through your server.\n */\n getAvatarUrl: (hash: string, options?: { size?: number, default?: string, rating?: string }) => string\n /**\n * Get a proxied avatar URL using the server-side hashing endpoint.\n * The email is sent to YOUR server (not Gravatar) for hashing.\n * Only available when the gravatar proxy is enabled.\n */\n getAvatarUrlFromEmail: (email: string, options?: { size?: number, default?: string, rating?: string }) => string\n}"
433
433
  }
434
434
  ],
435
435
  hotjar: [
package/dist/types.d.mts CHANGED
@@ -6,4 +6,4 @@ declare module '@nuxt/schema' {
6
6
 
7
7
  export { default } from './module.mjs'
8
8
 
9
- export { type FirstPartyOptions, type FirstPartyPrivacy, type ModuleHooks, type ModuleOptions } from './module.mjs'
9
+ export { type FirstPartyPrivacy, type ModuleHooks, type ModuleOptions } from './module.mjs'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nuxt/scripts",
3
3
  "type": "module",
4
- "version": "1.0.0-beta.31",
4
+ "version": "1.0.0-beta.32",
5
5
  "description": "Load third-party scripts with better performance, privacy and DX in Nuxt Apps.",
6
6
  "author": {
7
7
  "name": "Harlan Wilton",
@@ -144,7 +144,7 @@
144
144
  "vue": "^3.5.30",
145
145
  "vue-router": "^5.0.4",
146
146
  "vue-tsc": "^3.2.6",
147
- "@nuxt/scripts": "1.0.0-beta.31"
147
+ "@nuxt/scripts": "1.0.0-beta.32"
148
148
  },
149
149
  "resolutions": {
150
150
  "@nuxt/scripts": "workspace:*"