@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/module.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { existsSync, readdirSync, readFileSync } from 'node:fs';
2
- import { useLogger, addServerHandler, addPluginTemplate, useNuxt, addDevServerHandler, extendRouteRules, tryUseNuxt, extendViteConfig, logger as logger$1, addTypeTemplate, defineNuxtModule, createResolver, hasNuxtModule, addImports, addComponentsDir, addTemplate, addBuildPlugin } from '@nuxt/kit';
2
+ import { useNuxt, addDevServerHandler, extendRouteRules, tryUseNuxt, extendViteConfig, useLogger, addServerHandler, addPluginTemplate, logger as logger$1, addTypeTemplate, defineNuxtModule, createResolver, addImports, addComponentsDir, addTemplate, hasNuxtModule, addBuildPlugin } from '@nuxt/kit';
3
3
  import { defu } from 'defu';
4
4
  import { join, resolve, relative } from 'pathe';
5
5
  import { resolvePackageJSON, readPackageJSON } from 'pkg-types';
@@ -19,7 +19,108 @@ import { colors } from 'consola/utils';
19
19
  import MagicString from 'magic-string';
20
20
  import { hash } from 'ohash';
21
21
  import { registry } from './registry.mjs';
22
- import { g as getAllProxyConfigs } from './shared/scripts.D7e2ENu6.mjs';
22
+ import { b as buildProxyConfigsFromRegistry } from './shared/scripts.T4Z99VT8.mjs';
23
+
24
+ const renderedScript = /* @__PURE__ */ new Map();
25
+ const ONE_YEAR_IN_SECONDS = 60 * 60 * 24 * 365;
26
+ function bundleStorage() {
27
+ const nuxt = tryUseNuxt();
28
+ return createStorage({
29
+ driver: fsDriver({
30
+ base: resolve(nuxt?.options.rootDir || "", "node_modules/.cache/nuxt/scripts")
31
+ })
32
+ });
33
+ }
34
+ function setupPublicAssetStrategy(options = {}) {
35
+ const assetsBaseURL = options.prefix || "/_scripts/assets";
36
+ const nuxt = useNuxt();
37
+ const storage = bundleStorage();
38
+ addDevServerHandler({
39
+ route: assetsBaseURL,
40
+ handler: lazyEventHandler(async () => {
41
+ return eventHandler(async (event) => {
42
+ const cleanPath = (event.path || "").split("?")[0]?.slice(1) || "";
43
+ const filename = cleanPath;
44
+ const scriptDescriptor = renderedScript.get(join(assetsBaseURL, cleanPath));
45
+ if (!scriptDescriptor || scriptDescriptor instanceof Error)
46
+ throw createError({ statusCode: 404 });
47
+ if (scriptDescriptor.content) {
48
+ return scriptDescriptor.content;
49
+ }
50
+ const key = `bundle:${filename}`;
51
+ let res = await storage.getItemRaw(key);
52
+ if (!res) {
53
+ res = await fetch(scriptDescriptor.src).then((r) => r.arrayBuffer()).then((r) => Buffer.from(r));
54
+ await storage.setItemRaw(key, res);
55
+ }
56
+ return res;
57
+ });
58
+ })
59
+ });
60
+ if (nuxt.options.dev) {
61
+ extendRouteRules(joinURL(assetsBaseURL, "**"), {
62
+ cache: {
63
+ maxAge: ONE_YEAR_IN_SECONDS
64
+ }
65
+ });
66
+ }
67
+ const cacheDir = join(nuxt.options.buildDir, "cache", "scripts");
68
+ nuxt.hook("nitro:config", (nitroConfig) => {
69
+ nitroConfig.publicAssets ||= [];
70
+ nitroConfig.publicAssets.push({
71
+ dir: cacheDir,
72
+ maxAge: ONE_YEAR_IN_SECONDS,
73
+ baseURL: assetsBaseURL
74
+ });
75
+ nitroConfig.prerender ||= {};
76
+ nitroConfig.prerender.ignore ||= [];
77
+ nitroConfig.prerender.ignore.push(assetsBaseURL);
78
+ });
79
+ return {
80
+ renderedScript
81
+ };
82
+ }
83
+
84
+ const DEVTOOLS_UI_ROUTE = "/__nuxt-scripts";
85
+ const DEVTOOLS_UI_LOCAL_PORT = 3300;
86
+
87
+ async function setupDevToolsUI(options, resolve, nuxt = useNuxt()) {
88
+ const clientPath = await resolve("./client");
89
+ const isProductionBuild = existsSync(clientPath);
90
+ if (isProductionBuild) {
91
+ nuxt.hook("vite:serverCreated", async (server) => {
92
+ const sirv = await import('sirv').then((r) => r.default || r);
93
+ server.middlewares.use(
94
+ DEVTOOLS_UI_ROUTE,
95
+ sirv(clientPath, { dev: true, single: true })
96
+ );
97
+ });
98
+ } else {
99
+ extendViteConfig((config) => {
100
+ config.server = config.server || {};
101
+ config.server.proxy = config.server.proxy || {};
102
+ config.server.proxy[DEVTOOLS_UI_ROUTE] = {
103
+ target: `http://localhost:${DEVTOOLS_UI_LOCAL_PORT}${DEVTOOLS_UI_ROUTE}`,
104
+ changeOrigin: true,
105
+ followRedirects: true,
106
+ rewrite: (path) => path.replace(DEVTOOLS_UI_ROUTE, "")
107
+ };
108
+ });
109
+ }
110
+ addCustomTab({
111
+ // unique identifier
112
+ name: "nuxt-scripts",
113
+ // title to display in the tab
114
+ title: "Scripts",
115
+ // any icon from Iconify, or a URL to an image
116
+ icon: "carbon:script",
117
+ // iframe view
118
+ view: {
119
+ type: "iframe",
120
+ src: DEVTOOLS_UI_ROUTE
121
+ }
122
+ });
123
+ }
23
124
 
24
125
  function generatePartytownResolveUrl(proxyPrefix) {
25
126
  return `function(url, location, type) {
@@ -31,6 +132,32 @@ function generatePartytownResolveUrl(proxyPrefix) {
31
132
 
32
133
  const logger = useLogger("@nuxt/scripts");
33
134
 
135
+ function resolveCapabilities(script, scriptOptions) {
136
+ const defaults = script.defaultCapability ?? {};
137
+ const ceiling = script.capabilities ?? {};
138
+ const resolved = { ...defaults };
139
+ if (!scriptOptions)
140
+ return resolved;
141
+ const overrideKeys = ["reverseProxyIntercept", "bundle", "partytown"];
142
+ for (const key of overrideKeys) {
143
+ if (key in scriptOptions) {
144
+ const userValue = scriptOptions[key];
145
+ if (typeof userValue !== "boolean")
146
+ continue;
147
+ if (userValue && !ceiling[key]) {
148
+ if (import.meta.dev) {
149
+ logger.warn(
150
+ `[nuxt-scripts] Script "${script.registryKey}" does not support capability "${key}". This override will be ignored. Supported capabilities: ${JSON.stringify(ceiling)}`
151
+ );
152
+ }
153
+ continue;
154
+ }
155
+ resolved[key] = userValue;
156
+ }
157
+ }
158
+ return resolved;
159
+ }
160
+
34
161
  function generateInterceptPluginContents(proxyPrefix) {
35
162
  return `export default defineNuxtPlugin({
36
163
  name: 'nuxt-scripts:intercept',
@@ -78,7 +205,11 @@ function generateInterceptPluginContents(proxyPrefix) {
78
205
 
79
206
  globalThis.__nuxtScripts = {
80
207
  sendBeacon: (url, data) => origBeacon(proxyUrl(url), data),
81
- fetch: (url, opts) => origFetch(typeof url === 'string' ? proxyUrl(url) : url, opts),
208
+ fetch: (url, opts) => {
209
+ if (typeof url === 'string') return origFetch(proxyUrl(url), opts);
210
+ if (url instanceof Request) return origFetch(new Request(proxyUrl(url.url), url), opts);
211
+ return origFetch(url, opts);
212
+ },
82
213
  XMLHttpRequest: ProxiedXHR,
83
214
  Image: ProxiedImage,
84
215
  };
@@ -88,13 +219,12 @@ function generateInterceptPluginContents(proxyPrefix) {
88
219
  }
89
220
 
90
221
  async function setupFirstParty(config, resolvePath) {
91
- const enabled = !!config.firstParty;
92
- const proxyPrefix = typeof config.firstParty === "object" ? config.firstParty.proxyPrefix || "/_scripts/p" : "/_scripts/p";
93
- const privacy = typeof config.firstParty === "object" ? config.firstParty.privacy : void 0;
222
+ const proxyDisabled = config.proxy === false;
223
+ const proxyPrefix = typeof config.proxy === "object" ? config.proxy.prefix || "/_scripts/p" : "/_scripts/p";
224
+ const privacy = typeof config.proxy === "object" ? config.proxy.privacy : void 0;
94
225
  const assetsPrefix = config.assets?.prefix || "/_scripts/assets";
95
- const proxyConfigs = enabled ? getAllProxyConfigs() : {};
96
- const firstParty = { enabled, proxyPrefix, privacy, assetsPrefix, proxyConfigs };
97
- if (enabled) {
226
+ const firstParty = { enabled: !proxyDisabled, proxyPrefix, privacy, assetsPrefix, proxyConfigs: {} };
227
+ if (!proxyDisabled) {
98
228
  const proxyHandlerPath = await resolvePath("./runtime/server/proxy-handler");
99
229
  logger.debug("[nuxt-scripts] Registering proxy handler:", `${proxyPrefix}/**`, "->", proxyHandlerPath);
100
230
  addServerHandler({
@@ -110,7 +240,7 @@ function applyAutoInject(registry, runtimeConfig, proxyPrefix, registryKey, auto
110
240
  return;
111
241
  const input = entry[0];
112
242
  const scriptOptions = entry[1];
113
- if (input?.firstParty === false || scriptOptions?.firstParty === false)
243
+ if (input?.reverseProxyIntercept === false || scriptOptions?.reverseProxyIntercept === false)
114
244
  return;
115
245
  const rtScripts = runtimeConfig.public?.scripts;
116
246
  const rtEntry = rtScripts?.[registryKey];
@@ -132,7 +262,9 @@ function computePrivacyLevel(privacy) {
132
262
  }
133
263
  function finalizeFirstParty(opts) {
134
264
  const { firstParty, registryScripts, nuxtOptions } = opts;
135
- const { proxyConfigs, proxyPrefix } = firstParty;
265
+ const { proxyPrefix } = firstParty;
266
+ const proxyConfigs = buildProxyConfigsFromRegistry(registryScripts);
267
+ firstParty.proxyConfigs = proxyConfigs;
136
268
  const registryKeys = Object.keys(opts.registry || {});
137
269
  const scriptByKey = /* @__PURE__ */ new Map();
138
270
  for (const script of registryScripts) {
@@ -150,18 +282,17 @@ function finalizeFirstParty(opts) {
150
282
  unmatchedScripts.push(key);
151
283
  continue;
152
284
  }
153
- if (script.proxy === false)
285
+ if (!script.capabilities?.reverseProxyIntercept)
154
286
  continue;
155
287
  const registryEntry = opts.registry?.[key];
156
288
  const entryScriptOptions = registryEntry?.[1];
157
289
  const entryInput = registryEntry?.[0];
158
- if (entryScriptOptions?.firstParty === false || entryInput?.firstParty === false)
290
+ if (entryScriptOptions?.reverseProxyIntercept === false || entryInput?.reverseProxyIntercept === false)
159
291
  continue;
160
- const configKey = script.proxy || key;
292
+ const configKey = script.proxyConfig || key;
161
293
  const proxyConfig = proxyConfigs[configKey];
162
294
  if (!proxyConfig) {
163
- if (script.scriptBundling !== false)
164
- unsupportedScripts.push(key);
295
+ unsupportedScripts.push(key);
165
296
  continue;
166
297
  }
167
298
  for (const domain of proxyConfig.domains) {
@@ -236,7 +367,7 @@ Scripts will be bundled, but collection requests will not be proxied.
236
367
  Options:
237
368
  1. Configure platform rewrites (Vercel, Netlify, Cloudflare)
238
369
  2. Switch to server-rendered mode (ssr: true)
239
- 3. Disable with firstParty: false
370
+ 3. Disable with proxy: false
240
371
 
241
372
  See: https://scripts.nuxt.com/docs/guides/first-party#static-hosting`
242
373
  );
@@ -259,107 +390,6 @@ See: https://scripts.nuxt.com/docs/guides/first-party#static-hosting`
259
390
  return { proxyPrefix, devtools };
260
391
  }
261
392
 
262
- const renderedScript = /* @__PURE__ */ new Map();
263
- const ONE_YEAR_IN_SECONDS = 60 * 60 * 24 * 365;
264
- function bundleStorage() {
265
- const nuxt = tryUseNuxt();
266
- return createStorage({
267
- driver: fsDriver({
268
- base: resolve(nuxt?.options.rootDir || "", "node_modules/.cache/nuxt/scripts")
269
- })
270
- });
271
- }
272
- function setupPublicAssetStrategy(options = {}) {
273
- const assetsBaseURL = options.prefix || "/_scripts/assets";
274
- const nuxt = useNuxt();
275
- const storage = bundleStorage();
276
- addDevServerHandler({
277
- route: assetsBaseURL,
278
- handler: lazyEventHandler(async () => {
279
- return eventHandler(async (event) => {
280
- const cleanPath = (event.path || "").split("?")[0]?.slice(1) || "";
281
- const filename = cleanPath;
282
- const scriptDescriptor = renderedScript.get(join(assetsBaseURL, cleanPath));
283
- if (!scriptDescriptor || scriptDescriptor instanceof Error)
284
- throw createError({ statusCode: 404 });
285
- if (scriptDescriptor.content) {
286
- return scriptDescriptor.content;
287
- }
288
- const key = `bundle:${filename}`;
289
- let res = await storage.getItemRaw(key);
290
- if (!res) {
291
- res = await fetch(scriptDescriptor.src).then((r) => r.arrayBuffer()).then((r) => Buffer.from(r));
292
- await storage.setItemRaw(key, res);
293
- }
294
- return res;
295
- });
296
- })
297
- });
298
- if (nuxt.options.dev) {
299
- extendRouteRules(joinURL(assetsBaseURL, "**"), {
300
- cache: {
301
- maxAge: ONE_YEAR_IN_SECONDS
302
- }
303
- });
304
- }
305
- const cacheDir = join(nuxt.options.buildDir, "cache", "scripts");
306
- nuxt.hook("nitro:config", (nitroConfig) => {
307
- nitroConfig.publicAssets ||= [];
308
- nitroConfig.publicAssets.push({
309
- dir: cacheDir,
310
- maxAge: ONE_YEAR_IN_SECONDS,
311
- baseURL: assetsBaseURL
312
- });
313
- nitroConfig.prerender ||= {};
314
- nitroConfig.prerender.ignore ||= [];
315
- nitroConfig.prerender.ignore.push(assetsBaseURL);
316
- });
317
- return {
318
- renderedScript
319
- };
320
- }
321
-
322
- const DEVTOOLS_UI_ROUTE = "/__nuxt-scripts";
323
- const DEVTOOLS_UI_LOCAL_PORT = 3300;
324
-
325
- async function setupDevToolsUI(options, resolve, nuxt = useNuxt()) {
326
- const clientPath = await resolve("./client");
327
- const isProductionBuild = existsSync(clientPath);
328
- if (isProductionBuild) {
329
- nuxt.hook("vite:serverCreated", async (server) => {
330
- const sirv = await import('sirv').then((r) => r.default || r);
331
- server.middlewares.use(
332
- DEVTOOLS_UI_ROUTE,
333
- sirv(clientPath, { dev: true, single: true })
334
- );
335
- });
336
- } else {
337
- extendViteConfig((config) => {
338
- config.server = config.server || {};
339
- config.server.proxy = config.server.proxy || {};
340
- config.server.proxy[DEVTOOLS_UI_ROUTE] = {
341
- target: `http://localhost:${DEVTOOLS_UI_LOCAL_PORT}${DEVTOOLS_UI_ROUTE}`,
342
- changeOrigin: true,
343
- followRedirects: true,
344
- rewrite: (path) => path.replace(DEVTOOLS_UI_ROUTE, "")
345
- };
346
- });
347
- }
348
- addCustomTab({
349
- // unique identifier
350
- name: "nuxt-scripts",
351
- // title to display in the tab
352
- title: "Scripts",
353
- // any icon from Iconify, or a URL to an image
354
- icon: "carbon:script",
355
- // iframe view
356
- view: {
357
- type: "iframe",
358
- src: DEVTOOLS_UI_ROUTE
359
- }
360
- });
361
- }
362
-
363
393
  const isStackblitz = provider === "stackblitz";
364
394
  async function promptToInstall(name, installCommand, options) {
365
395
  if (await resolvePackageJSON(name).catch(() => null))
@@ -679,7 +709,8 @@ function rewriteScriptUrlsAST(content, filename, rewrites, postProcess, options)
679
709
  }
680
710
  if (node.type === "CallExpression" && !options?.skipApiRewrites) {
681
711
  const callee = node.callee;
682
- const canvasPropName = callee?.type === "MemberExpression" ? callee.computed ? callee.property?.type === "Literal" && typeof callee.property.value === "string" ? callee.property.value : null : callee.property?.name : null;
712
+ const shouldNeutralizeCanvas = options?.neutralizeCanvas !== false;
713
+ const canvasPropName = shouldNeutralizeCanvas && callee?.type === "MemberExpression" ? callee.computed ? callee.property?.type === "Literal" && typeof callee.property.value === "string" ? callee.property.value : null : callee.property?.name : null;
683
714
  if (canvasPropName === "toDataURL" && callee.object) {
684
715
  const blankCanvas = `"${BLANK_CANVAS_DATA_URL}"`;
685
716
  if (callee.object.type === "Identifier") {
@@ -786,7 +817,7 @@ function normalizeScriptData(src, assetsBaseURL = "/_scripts/assets") {
786
817
  return { url: src };
787
818
  }
788
819
  async function downloadScript(opts, renderedScript, fetchOptions, cacheMaxAge) {
789
- const { src, url, filename, forceDownload, integrity, proxyRewrites, postProcess, skipApiRewrites } = opts;
820
+ const { src, url, filename, forceDownload, integrity, proxyRewrites, postProcess, skipApiRewrites, neutralizeCanvas } = opts;
790
821
  if (src === url || !filename) {
791
822
  return;
792
823
  }
@@ -824,7 +855,7 @@ async function downloadScript(opts, renderedScript, fetchOptions, cacheMaxAge) {
824
855
  await storage.setItemRaw(`bundle:${filename}`, res);
825
856
  if (proxyRewrites?.length && res) {
826
857
  const content = res.toString("utf-8");
827
- const rewritten = rewriteScriptUrlsAST(content, filename || "script.js", proxyRewrites, postProcess, { skipApiRewrites });
858
+ const rewritten = rewriteScriptUrlsAST(content, filename || "script.js", proxyRewrites, postProcess, { skipApiRewrites, neutralizeCanvas });
828
859
  res = Buffer.from(rewritten, "utf-8");
829
860
  logger.debug(`Rewrote ${proxyRewrites.length} URL patterns in ${filename}`);
830
861
  }
@@ -1004,26 +1035,27 @@ function NuxtScriptBundleTransformer(options = {
1004
1035
  canBundle = bundleValue === true || bundleValue === "force" || String(bundleValue) === "true";
1005
1036
  forceDownload = bundleValue === "force";
1006
1037
  }
1007
- const firstPartyOption = scriptOptions?.value.properties?.find((prop) => {
1008
- return prop.type === "Property" && prop.key?.name === "firstParty" && prop.value.type === "Literal";
1038
+ const rpiOption = scriptOptions?.value.properties?.find((prop) => {
1039
+ return prop.type === "Property" && prop.key?.name === "reverseProxyIntercept" && prop.value.type === "Literal";
1009
1040
  });
1010
- let firstPartyOptOut = firstPartyOption?.value.value === false;
1041
+ let firstPartyOptOut = rpiOption?.value.value === false;
1011
1042
  if (!firstPartyOptOut && node.arguments[1]?.type === "ObjectExpression") {
1012
- const secondArgFirstPartyProp = node.arguments[1].properties.find(
1013
- (p) => p.type === "Property" && p.key?.name === "firstParty" && p.value.type === "Literal"
1043
+ const secondArgProp = node.arguments[1].properties.find(
1044
+ (p) => p.type === "Property" && p.key?.name === "reverseProxyIntercept" && p.value.type === "Literal"
1014
1045
  );
1015
- firstPartyOptOut = secondArgFirstPartyProp?.value.value === false;
1046
+ firstPartyOptOut = secondArgProp?.value.value === false;
1016
1047
  }
1017
1048
  if (!firstPartyOptOut && node.arguments[0]?.type === "ObjectExpression") {
1018
- const firstArgFirstPartyProp = node.arguments[0].properties.find(
1019
- (p) => p.type === "Property" && p.key?.name === "firstParty" && p.value.type === "Literal"
1049
+ const firstArgProp = node.arguments[0].properties.find(
1050
+ (p) => p.type === "Property" && p.key?.name === "reverseProxyIntercept" && p.value.type === "Literal"
1020
1051
  );
1021
- firstPartyOptOut = firstArgFirstPartyProp?.value.value === false;
1052
+ firstPartyOptOut = firstArgProp?.value.value === false;
1022
1053
  }
1023
1054
  if (canBundle) {
1024
1055
  const { url: _url, filename } = normalizeScriptData(src, options.assetsBaseURL);
1025
1056
  const script = options.scripts?.find((s2) => s2.import.name === fnName);
1026
- const proxyConfigKey = script?.proxy !== false ? script?.proxy || registryKey : void 0;
1057
+ const hasReverseProxy = script?.capabilities?.reverseProxyIntercept;
1058
+ const proxyConfigKey = hasReverseProxy ? script?.proxyConfig || registryKey : void 0;
1027
1059
  const proxyConfig = !firstPartyOptOut && proxyConfigKey ? options.proxyConfigs?.[proxyConfigKey] : void 0;
1028
1060
  const proxyRewrites = proxyConfig?.domains?.map((domain) => ({
1029
1061
  from: domain,
@@ -1031,10 +1063,11 @@ function NuxtScriptBundleTransformer(options = {
1031
1063
  }));
1032
1064
  const postProcess = proxyConfig?.postProcess;
1033
1065
  const skipApiRewrites = !!(registryKey && options.partytownScripts?.has(registryKey));
1066
+ const neutralizeCanvas = proxyConfig?.privacy !== void 0 && typeof proxyConfig.privacy === "object" ? proxyConfig.privacy.hardware ?? true : true;
1034
1067
  deferredOps.push(async () => {
1035
1068
  let url = _url;
1036
1069
  try {
1037
- await downloadScript({ src, url, filename, forceDownload, proxyRewrites, postProcess, integrity: options.integrity, skipApiRewrites }, renderedScript, options.fetchOptions, options.cacheMaxAge);
1070
+ await downloadScript({ src, url, filename, forceDownload, proxyRewrites, postProcess, integrity: options.integrity, skipApiRewrites, neutralizeCanvas }, renderedScript, options.fetchOptions, options.cacheMaxAge);
1038
1071
  } catch (e) {
1039
1072
  if (options.fallbackOnSrcOnBundleFail) {
1040
1073
  logger.warn(`[Nuxt Scripts: Bundle Transformer] Failed to bundle ${src}. Fallback to remote loading.`);
@@ -1408,7 +1441,6 @@ const module$1 = defineNuxtModule({
1408
1441
  }
1409
1442
  },
1410
1443
  defaults: {
1411
- firstParty: true,
1412
1444
  defaultScriptOptions: {
1413
1445
  trigger: "onNuxtReady"
1414
1446
  },
@@ -1485,37 +1517,11 @@ const module$1 = defineNuxtModule({
1485
1517
  };
1486
1518
  if (config.defaultScriptOptions?.bundle !== void 0) {
1487
1519
  logger.warn(
1488
- "`scripts.defaultScriptOptions.bundle` is deprecated. Use `scripts.firstParty: true` instead. First-party mode is now enabled by default."
1520
+ "`scripts.defaultScriptOptions.bundle` is deprecated. Bundling is now auto-enabled per-script via capabilities. Set `bundle: false` per-script to disable."
1489
1521
  );
1490
1522
  }
1491
1523
  const firstParty = await setupFirstParty(config, resolvePath);
1492
1524
  const assetsPrefix = firstParty.assetsPrefix;
1493
- if (config.partytown?.length) {
1494
- config.registry = config.registry || {};
1495
- const requiredForwards = [];
1496
- for (const scriptKey of config.partytown) {
1497
- const forwards = PARTYTOWN_FORWARDS[scriptKey];
1498
- if (forwards) {
1499
- requiredForwards.push(...forwards);
1500
- } else if (import.meta.dev) {
1501
- logger.warn(`[partytown] "${scriptKey}" has no known Partytown forwards configured. It may not work correctly or may require manual forward configuration.`);
1502
- }
1503
- const reg = config.registry;
1504
- const existing = reg[scriptKey];
1505
- if (existing) {
1506
- existing[1] = { ...existing[1], partytown: true };
1507
- } else {
1508
- reg[scriptKey] = [{}, { partytown: true }];
1509
- }
1510
- }
1511
- if (requiredForwards.length && hasNuxtModule("@nuxtjs/partytown")) {
1512
- const partytownConfig = nuxt.options.partytown || {};
1513
- const existingForwards = partytownConfig.forward || [];
1514
- const newForwards = [.../* @__PURE__ */ new Set([...existingForwards, ...requiredForwards])];
1515
- nuxt.options.partytown = { ...partytownConfig, forward: newForwards };
1516
- logger.info(`[partytown] Auto-configured forwards: ${requiredForwards.join(", ")}`);
1517
- }
1518
- }
1519
1525
  const composables = [
1520
1526
  "useScript",
1521
1527
  "useScriptEventPage",
@@ -1572,6 +1578,41 @@ const module$1 = defineNuxtModule({
1572
1578
  });
1573
1579
  }
1574
1580
  const { renderedScript } = setupPublicAssetStrategy(config.assets);
1581
+ const partytownScripts = /* @__PURE__ */ new Set();
1582
+ const scriptByKey = /* @__PURE__ */ new Map();
1583
+ for (const script of registryScripts) {
1584
+ if (script.registryKey)
1585
+ scriptByKey.set(script.registryKey, script);
1586
+ }
1587
+ let anyNeedsProxy = false;
1588
+ const registryKeys = Object.keys(config.registry || {});
1589
+ for (const key of registryKeys) {
1590
+ const script = scriptByKey.get(key);
1591
+ if (!script)
1592
+ continue;
1593
+ const entry = config.registry?.[key];
1594
+ const scriptOptions = entry?.[1] || {};
1595
+ const inputOptions = entry?.[0] || {};
1596
+ const mergedOverrides = { ...inputOptions, ...scriptOptions };
1597
+ const resolved = resolveCapabilities(script, mergedOverrides);
1598
+ if (resolved.reverseProxyIntercept)
1599
+ anyNeedsProxy = true;
1600
+ if (resolved.partytown) {
1601
+ partytownScripts.add(key);
1602
+ const forwards = PARTYTOWN_FORWARDS[key];
1603
+ if (forwards?.length && hasNuxtModule("@nuxtjs/partytown")) {
1604
+ const partytownConfig = nuxt.options.partytown || {};
1605
+ const existingForwards = partytownConfig.forward || [];
1606
+ const newForwards = [.../* @__PURE__ */ new Set([...existingForwards, ...forwards])];
1607
+ nuxt.options.partytown = { ...partytownConfig, forward: newForwards };
1608
+ } else if (!forwards && import.meta.dev) {
1609
+ logger.warn(`[partytown] "${key}" has no known Partytown forwards configured. It may not work correctly or may require manual forward configuration.`);
1610
+ }
1611
+ }
1612
+ }
1613
+ if (firstParty.enabled && !anyNeedsProxy) {
1614
+ firstParty.enabled = false;
1615
+ }
1575
1616
  if (firstParty.enabled) {
1576
1617
  const { proxyPrefix, devtools: devtoolsData } = finalizeFirstParty({
1577
1618
  firstParty,
@@ -1582,14 +1623,14 @@ const module$1 = defineNuxtModule({
1582
1623
  if (devtoolsData) {
1583
1624
  nuxt.options.runtimeConfig.public["nuxt-scripts-devtools"] = devtoolsData;
1584
1625
  }
1585
- if (config.partytown?.length && hasNuxtModule("@nuxtjs/partytown")) {
1626
+ if (partytownScripts.size && hasNuxtModule("@nuxtjs/partytown")) {
1586
1627
  const partytownConfig = nuxt.options.partytown || {};
1587
1628
  if (!partytownConfig.resolveUrl) {
1588
1629
  partytownConfig.resolveUrl = generatePartytownResolveUrl(proxyPrefix);
1589
1630
  nuxt.options.partytown = partytownConfig;
1590
1631
  logger.info("[partytown] Auto-configured resolveUrl for first-party proxy");
1591
1632
  } else {
1592
- logger.warn("[partytown] Custom resolveUrl already set \u2014 first-party proxy URLs will not be auto-rewritten in Partytown worker. Add first-party proxy rules to your resolveUrl manually.");
1633
+ logger.warn("[partytown] Custom resolveUrl already set. Add first-party proxy rules to your resolveUrl manually.");
1593
1634
  }
1594
1635
  }
1595
1636
  }
@@ -1603,7 +1644,7 @@ const module$1 = defineNuxtModule({
1603
1644
  defaultBundle: firstParty.enabled || config.defaultScriptOptions?.bundle,
1604
1645
  proxyConfigs: firstParty.proxyConfigs,
1605
1646
  proxyPrefix: firstParty.proxyPrefix,
1606
- partytownScripts: new Set(config.partytown || []),
1647
+ partytownScripts,
1607
1648
  moduleDetected(module) {
1608
1649
  if (nuxt.options.dev && module !== "@nuxt/scripts" && !moduleInstallPromises.has(module) && !hasNuxtModule(module))
1609
1650
  moduleInstallPromises.set(module, () => installNuxtModule(module));
@@ -1,6 +1,11 @@
1
1
  import { ResolvePathOptions } from '@nuxt/kit';
2
+ import { ProxyPrivacyInput } from '../dist/runtime/server/utils/privacy.js';
2
3
  import { RegistryScript } from '../dist/runtime/types.js';
3
4
 
5
+ declare const PRIVACY_NONE: ProxyPrivacyInput;
6
+ declare const PRIVACY_FULL: ProxyPrivacyInput;
7
+ declare const PRIVACY_HEATMAP: ProxyPrivacyInput;
8
+ declare const PRIVACY_IP_ONLY: ProxyPrivacyInput;
4
9
  declare function registry(resolve?: (path: string, opts?: ResolvePathOptions | undefined) => Promise<string>): Promise<RegistryScript[]>;
5
10
 
6
- export { registry };
11
+ export { PRIVACY_FULL, PRIVACY_HEATMAP, PRIVACY_IP_ONLY, PRIVACY_NONE, registry };
@@ -1,6 +1,11 @@
1
1
  import { ResolvePathOptions } from '@nuxt/kit';
2
+ import { ProxyPrivacyInput } from '../dist/runtime/server/utils/privacy.js';
2
3
  import { RegistryScript } from '../dist/runtime/types.js';
3
4
 
5
+ declare const PRIVACY_NONE: ProxyPrivacyInput;
6
+ declare const PRIVACY_FULL: ProxyPrivacyInput;
7
+ declare const PRIVACY_HEATMAP: ProxyPrivacyInput;
8
+ declare const PRIVACY_IP_ONLY: ProxyPrivacyInput;
4
9
  declare function registry(resolve?: (path: string, opts?: ResolvePathOptions | undefined) => Promise<string>): Promise<RegistryScript[]>;
5
10
 
6
- export { registry };
11
+ export { PRIVACY_FULL, PRIVACY_HEATMAP, PRIVACY_IP_ONLY, PRIVACY_NONE, registry };