@nuxt/scripts 1.3.3 → 1.3.4

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 (96) hide show
  1. package/dist/devtools-client/200.html +1 -1
  2. package/dist/devtools-client/404.html +1 -1
  3. package/dist/devtools-client/_nuxt/{DAubxma0.js → 8ltZ0o6d.js} +1 -1
  4. package/dist/devtools-client/_nuxt/{CBuBrHyL.js → B8_EBdhg.js} +1 -1
  5. package/dist/devtools-client/_nuxt/CC0GKROJ.js +1 -0
  6. package/dist/devtools-client/_nuxt/{DvC3yV2P.js → CMXzQxJZ.js} +1 -1
  7. package/dist/devtools-client/_nuxt/{xAZ2vgo3.js → CP7c-Js6.js} +4 -4
  8. package/dist/devtools-client/_nuxt/{DzbSCA_w.js → DTP8MRtW.js} +1 -1
  9. package/dist/devtools-client/_nuxt/{DgAtAWdT.js → Dkc7iTdR.js} +1 -1
  10. package/dist/devtools-client/_nuxt/Dl7W1ViV.js +28 -0
  11. package/dist/devtools-client/_nuxt/{WOtyQdps.js → KxC4Q3ev.js} +1 -1
  12. package/dist/devtools-client/_nuxt/builds/latest.json +1 -1
  13. package/dist/devtools-client/_nuxt/builds/meta/c38edf4f-387c-4148-a34a-ca78a5b40869.json +1 -0
  14. package/dist/devtools-client/_nuxt/error-404.Bq2JQbJs.css +1 -0
  15. package/dist/devtools-client/_nuxt/error-500.5E_FOzlc.css +1 -0
  16. package/dist/devtools-client/_nuxt/{pages.BF1VnccH.css → pages.aU4WirOM.css} +1 -1
  17. package/dist/devtools-client/docs/index.html +1 -1
  18. package/dist/devtools-client/first-party/index.html +1 -1
  19. package/dist/devtools-client/index.html +1 -1
  20. package/dist/devtools-client/registry/index.html +1 -1
  21. package/dist/module.d.mts +1 -1
  22. package/dist/module.d.ts +1 -1
  23. package/dist/module.json +1 -1
  24. package/dist/module.mjs +263 -47
  25. package/dist/registry.mjs +2 -2
  26. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue +71 -21
  27. package/dist/runtime/components/GoogleMaps/useGoogleMapsResource.d.ts +2 -1
  28. package/dist/runtime/components/GoogleMaps/useGoogleMapsResource.js +39 -25
  29. package/dist/runtime/components/ScriptCarbonAds.vue +11 -3
  30. package/dist/runtime/components/ScriptCrisp.vue +4 -1
  31. package/dist/runtime/components/ScriptIntercom.vue +4 -1
  32. package/dist/runtime/components/ScriptLemonSqueezy.d.vue.ts +13 -13
  33. package/dist/runtime/components/ScriptLemonSqueezy.vue +30 -6
  34. package/dist/runtime/components/ScriptLemonSqueezy.vue.d.ts +13 -13
  35. package/dist/runtime/components/ScriptPayPalButtons.vue +8 -1
  36. package/dist/runtime/components/ScriptPayPalMessages.vue +6 -0
  37. package/dist/runtime/components/ScriptStripePricingTable.vue +2 -0
  38. package/dist/runtime/components/ScriptVimeoPlayer.vue +8 -1
  39. package/dist/runtime/composables/useScript.js +121 -44
  40. package/dist/runtime/composables/useScriptEventPage.js +36 -20
  41. package/dist/runtime/composables/useScriptTriggerIdleTimeout.js +19 -5
  42. package/dist/runtime/composables/useScriptTriggerInteraction.js +23 -10
  43. package/dist/runtime/composables/useScriptTriggerServiceWorker.js +21 -18
  44. package/dist/runtime/devtools-standalone-bridge.client.js +28 -3
  45. package/dist/runtime/npm-script-proxy.d.ts +7 -0
  46. package/dist/runtime/npm-script-proxy.js +46 -0
  47. package/dist/runtime/npm-script-stub.js +4 -5
  48. package/dist/runtime/registry/posthog.js +11 -3
  49. package/dist/runtime/registry/speedcurve.js +33 -4
  50. package/dist/runtime/registry/usercentrics.js +4 -21
  51. package/dist/runtime/registry/youtube-player.js +16 -5
  52. package/dist/runtime/server/bluesky-embed.js +15 -6
  53. package/dist/runtime/server/google-maps-geocode-proxy.js +10 -5
  54. package/dist/runtime/server/google-static-maps-proxy.js +20 -13
  55. package/dist/runtime/server/gravatar-proxy.js +48 -11
  56. package/dist/runtime/server/instagram-embed-asset.js +1 -1
  57. package/dist/runtime/server/instagram-embed.js +44 -94
  58. package/dist/runtime/server/proxy-handler.d.ts +2 -1
  59. package/dist/runtime/server/proxy-handler.js +183 -23
  60. package/dist/runtime/server/utils/cache-config.d.ts +14 -0
  61. package/dist/runtime/server/utils/cache-config.js +13 -0
  62. package/dist/runtime/server/utils/cached-upstream.d.ts +23 -2
  63. package/dist/runtime/server/utils/cached-upstream.js +212 -15
  64. package/dist/runtime/server/utils/image-proxy.d.ts +3 -2
  65. package/dist/runtime/server/utils/image-proxy.js +26 -16
  66. package/dist/runtime/server/utils/instagram-embed.d.ts +8 -0
  67. package/dist/runtime/server/utils/instagram-embed.js +155 -0
  68. package/dist/runtime/server/utils/network-host.d.ts +21 -0
  69. package/dist/runtime/server/utils/network-host.js +112 -0
  70. package/dist/runtime/server/utils/privacy.js +55 -19
  71. package/dist/runtime/server/utils/proxy-query.d.ts +2 -0
  72. package/dist/runtime/server/utils/proxy-query.js +10 -0
  73. package/dist/runtime/server/utils/sign.d.ts +1 -1
  74. package/dist/runtime/server/utils/sign.js +1 -1
  75. package/dist/runtime/server/utils/withSigning.d.ts +1 -1
  76. package/dist/runtime/server/utils/withSigning.js +3 -3
  77. package/dist/runtime/server/vercel-insights-sink.js +1 -1
  78. package/dist/runtime/server/x-embed.js +8 -4
  79. package/dist/runtime/unhead-features.d.ts +1 -0
  80. package/dist/runtime/unhead-features.js +3 -0
  81. package/dist/runtime/utils/abortable-promise.d.ts +8 -0
  82. package/dist/runtime/utils/abortable-promise.js +63 -0
  83. package/dist/runtime/utils/after-next-paint.d.ts +1 -1
  84. package/dist/runtime/utils/after-next-paint.js +16 -1
  85. package/dist/runtime/utils/usercentrics-consent.d.ts +10 -0
  86. package/dist/runtime/utils/usercentrics-consent.js +88 -0
  87. package/dist/runtime/utils/youtube-readiness.d.ts +7 -0
  88. package/dist/runtime/utils/youtube-readiness.js +45 -0
  89. package/dist/runtime/utils.d.ts +3 -1
  90. package/dist/runtime/utils.js +29 -0
  91. package/package.json +2 -1
  92. package/dist/devtools-client/_nuxt/BGGk5RYW.js +0 -1
  93. package/dist/devtools-client/_nuxt/C8xLTMBy.js +0 -28
  94. package/dist/devtools-client/_nuxt/builds/meta/0c193d7f-fdc4-4ec6-b4c0-7ba4cc94709b.json +0 -1
  95. package/dist/devtools-client/_nuxt/error-404.CIn5oEzb.css +0 -1
  96. package/dist/devtools-client/_nuxt/error-500.B1YZl8g8.css +0 -1
package/dist/module.d.mts CHANGED
@@ -30,7 +30,7 @@ interface ResolvedProxySecret {
30
30
  * 3. Dev-only auto-generation: write to `.env` (or keep in memory as last resort)
31
31
  * 4. Empty string (prod without secret; caller decides whether this is fatal)
32
32
  */
33
- declare function resolveProxySecret(rootDir: string, isDev: boolean, configSecret?: string, autoGenerate?: boolean): ResolvedProxySecret | undefined;
33
+ declare function resolveProxySecret(rootDir: string, isDev: boolean, configSecret?: string, autoGenerate?: boolean): Promise<ResolvedProxySecret | undefined>;
34
34
  declare function isProxyDisabled(registryKey: string, registry?: NuxtConfigScriptRegistry, runtimeConfig?: Record<string, any>): boolean;
35
35
  declare function applyAutoInject(registry: NuxtConfigScriptRegistry, runtimeConfig: Record<string, any>, proxyPrefix: string, registryKey: string, autoInject: ResolvedProxyAutoInject, alias?: ProxyAliasConfig): void;
36
36
  declare function resolveConfiguredProxyDomains(config: Record<string, any> | undefined, proxyConfig?: Pick<ProxyConfig, 'autoInject' | 'configDomainFields'>): string[];
package/dist/module.d.ts CHANGED
@@ -30,7 +30,7 @@ interface ResolvedProxySecret {
30
30
  * 3. Dev-only auto-generation: write to `.env` (or keep in memory as last resort)
31
31
  * 4. Empty string (prod without secret; caller decides whether this is fatal)
32
32
  */
33
- declare function resolveProxySecret(rootDir: string, isDev: boolean, configSecret?: string, autoGenerate?: boolean): ResolvedProxySecret | undefined;
33
+ declare function resolveProxySecret(rootDir: string, isDev: boolean, configSecret?: string, autoGenerate?: boolean): Promise<ResolvedProxySecret | undefined>;
34
34
  declare function isProxyDisabled(registryKey: string, registry?: NuxtConfigScriptRegistry, runtimeConfig?: Record<string, any>): boolean;
35
35
  declare function applyAutoInject(registry: NuxtConfigScriptRegistry, runtimeConfig: Record<string, any>, proxyPrefix: string, registryKey: string, autoInject: ResolvedProxyAutoInject, alias?: ProxyAliasConfig): void;
36
36
  declare function resolveConfiguredProxyDomains(config: Record<string, any> | undefined, proxyConfig?: Pick<ProxyConfig, 'autoInject' | 'configDomainFields'>): string[];
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.16"
6
6
  },
7
- "version": "1.3.3",
7
+ "version": "1.3.4",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -1,23 +1,27 @@
1
1
  import { createHash, randomBytes } from 'node:crypto';
2
- import { existsSync, readFileSync, appendFileSync, writeFileSync, readdirSync } from 'node:fs';
3
- import { useNuxt, addDevServerHandler, extendRouteRules, tryUseNuxt, createResolver, extendViteConfig, logger as logger$1, useLogger, addTypeTemplate, defineNuxtModule, addPluginTemplate, addServerHandler, addImports, addComponentsDir, addTemplate, hasNuxtModule, addBuildPlugin, addPlugin } from '@nuxt/kit';
2
+ import { existsSync, readFileSync, writeFileSync, appendFileSync, readdirSync } from 'node:fs';
3
+ import fsp, { open, stat, unlink } from 'node:fs/promises';
4
+ import { setTimeout } from 'node:timers/promises';
5
+ import { useNuxt, addDevServerHandler, extendRouteRules, tryUseNuxt, createResolver, extendViteConfig, logger as logger$1, useLogger, getNuxtVersion, addTypeTemplate, resolvePath, defineNuxtModule, addPluginTemplate, addServerHandler, addImports, addComponentsDir, addTemplate, hasNuxtModule, addBuildPlugin, addPlugin } from '@nuxt/kit';
4
6
  import { defu } from 'defu';
5
- import { join, resolve } from 'pathe';
7
+ import { join, resolve, dirname } from 'pathe';
6
8
  import { resolvePackageJSON, readPackageJSON } from 'pkg-types';
7
9
  import { lazyEventHandler, eventHandler, createError, setHeader } from 'h3';
8
10
  import { fetch, $fetch } from 'ofetch';
9
11
  import { joinURL, parseURL, parseQuery, hasProtocol } from 'ufo';
10
12
  import { createStorage } from 'unstorage';
11
13
  import fsDriver from 'unstorage/drivers/fs-lite';
14
+ import { Buffer as Buffer$1 } from 'node:buffer';
12
15
  import { isCI, provider } from 'std-env';
16
+ import { pathToFileURL } from 'node:url';
13
17
  import { parseAndWalk, ScopeTracker, walk, ScopeTrackerFunction, ScopeTrackerIdentifier, ScopeTrackerFunctionParam, ScopeTrackerVariable } from 'oxc-walker';
14
18
  import { createUnplugin } from 'unplugin';
15
- import { pathToFileURL } from 'node:url';
16
- import fsp from 'node:fs/promises';
17
19
  import { colors } from 'consola/utils';
18
20
  import MagicString from 'magic-string';
19
21
  import { hash } from 'ohash';
20
22
  import { getBundleResolve, registry, resolveCapabilities, getPartytownForwards, buildProxyConfigsFromRegistry, generatePartytownResolveUrl } from './registry.mjs';
23
+ import { ensureNuxtScriptsCacheStorage } from '../dist/runtime/server/utils/cache-config.js';
24
+ import { isPublicNetworkHostname } from '../dist/runtime/server/utils/network-host.js';
21
25
  import '../dist/runtime/registry/schemas.js';
22
26
 
23
27
  const renderedScript = /* @__PURE__ */ new Map();
@@ -83,6 +87,7 @@ function setupPublicAssetStrategy(assetsBaseURL) {
83
87
  const DEVTOOLS_UI_ROUTE = "/__nuxt-scripts";
84
88
  const DEVTOOLS_UI_LOCAL_PORT = 3030;
85
89
  const DEVTOOLS_API_STATE_ROUTE = "/__nuxt-scripts-api/state";
90
+ const DEVTOOLS_API_MAX_BODY_SIZE = 2 * 1024 * 1024;
86
91
  async function setupDevtools(nuxt, options = {}) {
87
92
  const { addCustomTab } = await import('@nuxt/devtools-kit');
88
93
  const { resolve } = createResolver(import.meta.url);
@@ -139,13 +144,38 @@ function setupStandaloneApi(nuxt) {
139
144
  return;
140
145
  }
141
146
  if (req.method === "POST") {
142
- let body = "";
143
- req.on("data", (chunk) => {
144
- body += chunk.toString();
145
- });
146
- req.on("end", () => {
147
+ let cleanup = function() {
148
+ req.off("data", onData);
149
+ req.off("end", onEnd);
150
+ req.off("aborted", onAborted);
151
+ req.off("error", onAborted);
152
+ }, onAborted = function() {
153
+ finished = true;
154
+ chunks = [];
155
+ cleanup();
156
+ }, onData = function(chunk) {
157
+ if (finished)
158
+ return;
159
+ size += chunk.byteLength;
160
+ if (size > DEVTOOLS_API_MAX_BODY_SIZE) {
161
+ finished = true;
162
+ chunks = [];
163
+ cleanup();
164
+ req.once("error", () => {
165
+ });
166
+ req.resume();
167
+ res.statusCode = 413;
168
+ res.end("payload too large");
169
+ return;
170
+ }
171
+ chunks.push(chunk);
172
+ }, onEnd = function() {
173
+ if (finished)
174
+ return;
175
+ finished = true;
176
+ cleanup();
147
177
  try {
148
- const data = JSON.parse(body);
178
+ const data = JSON.parse(Buffer$1.concat(chunks, size).toString("utf8"));
149
179
  scriptsState = { ...data, updatedAt: Date.now() };
150
180
  res.statusCode = 200;
151
181
  res.end("ok");
@@ -153,7 +183,15 @@ function setupStandaloneApi(nuxt) {
153
183
  res.statusCode = 400;
154
184
  res.end("invalid json");
155
185
  }
156
- });
186
+ chunks = [];
187
+ };
188
+ let chunks = [];
189
+ let size = 0;
190
+ let finished = false;
191
+ req.on("data", onData);
192
+ req.on("end", onEnd);
193
+ req.on("aborted", onAborted);
194
+ req.on("error", onAborted);
157
195
  return;
158
196
  }
159
197
  res.statusCode = 405;
@@ -214,8 +252,11 @@ function buildDevtoolsData(proxyPrefix, privacyLabel, scripts, aliasToDomain) {
214
252
 
215
253
  const isStackblitz = provider === "stackblitz";
216
254
  async function promptToInstall(name, installCommand, options) {
217
- if (await resolvePackageJSON(name).catch(() => null))
255
+ if (await resolvePackageJSON(name).catch(() => {
256
+ return null;
257
+ })) {
218
258
  return true;
259
+ }
219
260
  logger$1.info(`Package ${name} is missing`);
220
261
  if (isCI)
221
262
  return false;
@@ -254,6 +295,89 @@ function installNuxtModule(name, options) {
254
295
 
255
296
  const logger = useLogger("@nuxt/scripts");
256
297
 
298
+ const NITRO_RUNTIME_MODULE = "#nuxt-scripts/nitro";
299
+ const H3_RUNTIME_MODULE = "#nuxt-scripts/h3";
300
+ const TYPE_TEMPLATE_FILENAME = "types/nuxt-scripts-nitro.d.ts";
301
+ const defaultDependencies = {
302
+ addTypeTemplate,
303
+ getNuxtVersion
304
+ };
305
+ const nitroV2Runtime = `export {
306
+ defineCachedFunction,
307
+ useNitroApp,
308
+ useRuntimeConfig,
309
+ } from 'nitropack/runtime'
310
+ `;
311
+ const nitroV3RuntimeTypes = `export { useNitroApp } from 'nitro/app'
312
+ export { defineCachedFunction } from 'nitro/cache'
313
+ export function useRuntimeConfig(event?: import('nitro/h3').H3Event): ReturnType<typeof import('nitro/runtime-config').useRuntimeConfig>
314
+ `;
315
+ function indent(value, spaces) {
316
+ const padding = " ".repeat(spaces);
317
+ return value.split("\n").map((line) => `${padding}${line}`).join("\n");
318
+ }
319
+ function renderRuntimeDeclarations(compatibility) {
320
+ const nitroRuntime = compatibility._tag === "nitro-v3" ? nitroV3RuntimeTypes : nitroV2Runtime;
321
+ const h3Runtime = compatibility._tag === "nitro-v3" ? `export * from 'nitro/h3'
322
+ ` : `export * from 'h3'
323
+ `;
324
+ return `declare module '${NITRO_RUNTIME_MODULE}' {
325
+ ${indent(nitroRuntime.trim(), 2)}
326
+ }
327
+
328
+ declare module '${H3_RUNTIME_MODULE}' {
329
+ ${indent(h3Runtime.trim(), 2)}
330
+ }
331
+ `;
332
+ }
333
+ function renderNitroV3Runtime(compatibility) {
334
+ return `export { useNitroApp } from ${JSON.stringify(compatibility.app)}
335
+ export { defineCachedFunction } from ${JSON.stringify(compatibility.cache)}
336
+ import { useRuntimeConfig as _useRuntimeConfig } from ${JSON.stringify(compatibility.runtimeConfig)}
337
+ export function useRuntimeConfig(_event) { return _useRuntimeConfig() }
338
+ `;
339
+ }
340
+ function applyNitroRuntimeCompatibility(nuxt, compatibility) {
341
+ const nuxtOptions = nuxt.options;
342
+ const nitroOptions = nuxtOptions.nitro ||= {};
343
+ const h3Runtime = compatibility._tag === "nitro-v3" ? compatibility.h3 : "h3";
344
+ nitroOptions.alias ||= {};
345
+ nitroOptions.virtual ||= {};
346
+ const nuxtAliases = nuxtOptions.alias ||= {};
347
+ delete nuxtAliases[H3_RUNTIME_MODULE];
348
+ nuxtOptions.alias = { [H3_RUNTIME_MODULE]: h3Runtime, ...nuxtAliases };
349
+ nitroOptions.alias[H3_RUNTIME_MODULE] = h3Runtime;
350
+ nitroOptions.virtual[NITRO_RUNTIME_MODULE] = compatibility._tag === "nitro-v3" ? renderNitroV3Runtime(compatibility) : nitroV2Runtime;
351
+ }
352
+ async function createNuxtNitroImportResolver() {
353
+ const nuxtDir = dirname(await resolvePath("nuxt/package.json"));
354
+ const nitroDir = dirname(await resolvePath("@nuxt/nitro-server/package.json", { cwd: nuxtDir }));
355
+ return async (id) => {
356
+ const resolved = await resolvePath(id, { cwd: nitroDir });
357
+ if (!existsSync(resolved))
358
+ throw new Error(`[nuxt-scripts] Could not resolve Nitro runtime helper "${id}" from "${nitroDir}".`);
359
+ return pathToFileURL(resolved).href;
360
+ };
361
+ }
362
+ async function resolveNitroV3Compatibility(resolveNitroImport) {
363
+ const [app, cache, h3, runtimeConfig] = await Promise.all([
364
+ resolveNitroImport("nitro/app"),
365
+ resolveNitroImport("nitro/cache"),
366
+ resolveNitroImport("nitro/h3"),
367
+ resolveNitroImport("nitro/runtime-config")
368
+ ]);
369
+ return { _tag: "nitro-v3", app, cache, h3, runtimeConfig };
370
+ }
371
+ async function setupNitroRuntimeCompatibility(nuxt, dependencies = defaultDependencies) {
372
+ const compatibility = Number.parseInt(dependencies.getNuxtVersion(nuxt), 10) >= 5 ? await resolveNitroV3Compatibility(dependencies.resolveNitroImport || await createNuxtNitroImportResolver()) : { _tag: "nitro-v2" };
373
+ applyNitroRuntimeCompatibility(nuxt, compatibility);
374
+ nuxt.hooks.hookOnce("modules:done", () => applyNitroRuntimeCompatibility(nuxt, compatibility));
375
+ dependencies.addTypeTemplate({
376
+ filename: TYPE_TEMPLATE_FILENAME,
377
+ getContents: async () => renderRuntimeDeclarations(compatibility)
378
+ }, { nitro: true, node: true, nuxt: true });
379
+ }
380
+
257
381
  const SCRIPT_OPTION_KEYS = ["trigger", "proxy", "bundle", "partytown"];
258
382
  function extractRequiredFields(schema) {
259
383
  if (!schema)
@@ -424,12 +548,14 @@ function NuxtScriptsCheckScripts() {
424
548
 
425
549
  function generateInterceptPluginContents(proxyPrefix, options) {
426
550
  const testMode = options?.testMode ?? false;
427
- return `export default defineNuxtPlugin({
551
+ return `import { defineNuxtPlugin } from 'nuxt/app'
552
+
553
+ export default defineNuxtPlugin({
428
554
  name: 'nuxt-scripts:intercept',
429
555
  enforce: 'pre',
430
556
  setup() {
431
557
  const proxyPrefix = ${JSON.stringify(proxyPrefix)};
432
- const domainAliases = ${JSON.stringify(options?.domainAliases ?? {})};
558
+ const domainAliases = Object.assign(Object.create(null), ${JSON.stringify(options?.domainAliases ?? {})});
433
559
  const origBeacon = typeof navigator !== 'undefined' && navigator.sendBeacon
434
560
  ? navigator.sendBeacon.bind(navigator)
435
561
  : () => false;
@@ -438,11 +564,11 @@ function generateInterceptPluginContents(proxyPrefix, options) {
438
564
  function proxyUrl(url) {
439
565
  try {
440
566
  const parsed = new URL(url, location.origin);
441
- if (parsed.origin !== location.origin) {
567
+ if ((parsed.protocol === 'http:' || parsed.protocol === 'https:') && parsed.origin !== location.origin) {
442
568
  const seg = domainAliases[parsed.host] || parsed.host;
443
569
  return location.origin + proxyPrefix + '/' + seg + parsed.pathname + parsed.search;
444
570
  }
445
- } catch {}
571
+ } catch { /* Invalid URL inputs retain native behavior. */ }
446
572
  return url;
447
573
  }
448
574
 
@@ -1339,7 +1465,7 @@ function NuxtScriptBundleTransformer(options = {
1339
1465
  const WILDCARD_RE = /\*/;
1340
1466
  const SAFE_ALIAS_SEGMENT_RE = /^[\w.-]+$/;
1341
1467
  function isSafeAliasSegment(alias) {
1342
- return SAFE_ALIAS_SEGMENT_RE.test(alias);
1468
+ return alias !== "." && alias !== ".." && SAFE_ALIAS_SEGMENT_RE.test(alias);
1343
1469
  }
1344
1470
  function aliasForDomain(domain, alias) {
1345
1471
  if (!alias || WILDCARD_RE.test(domain))
@@ -1349,19 +1475,16 @@ function aliasForDomain(domain, alias) {
1349
1475
  return Object.hasOwn(alias, domain) ? alias[domain] || void 0 : void 0;
1350
1476
  }
1351
1477
  function buildDomainAliasMap(domains, alias) {
1352
- const map = {};
1478
+ const entries = [];
1353
1479
  for (const domain of domains) {
1354
1480
  const value = aliasForDomain(domain, alias);
1355
1481
  if (value)
1356
- map[domain] = value;
1482
+ entries.push([domain, value]);
1357
1483
  }
1358
- return map;
1484
+ return Object.fromEntries(entries);
1359
1485
  }
1360
1486
  function invertAliasMap(map) {
1361
- const out = {};
1362
- for (const [domain, alias] of Object.entries(map))
1363
- out[alias] = domain;
1364
- return out;
1487
+ return Object.fromEntries(Object.entries(map).map(([domain, alias]) => [alias, domain]));
1365
1488
  }
1366
1489
  function aliasProxyValue(value, proxyPrefix, alias) {
1367
1490
  const prefix = `${proxyPrefix}/`;
@@ -1595,6 +1718,20 @@ function templatePlugin(config, registry) {
1595
1718
  ].join("\n");
1596
1719
  }
1597
1720
 
1721
+ const SOURCE_LESS_SCRIPT_LOADER_TYPE = /\bUseScriptLoaderInput\b/;
1722
+ function hasUnheadSourceLessScriptLoader(typesSource) {
1723
+ return SOURCE_LESS_SCRIPT_LOADER_TYPE.test(typesSource);
1724
+ }
1725
+ function hasUnheadSourceLessScriptLoaderFile(typesPath) {
1726
+ if (!typesPath || !existsSync(typesPath))
1727
+ return false;
1728
+ try {
1729
+ return hasUnheadSourceLessScriptLoader(readFileSync(typesPath, "utf8"));
1730
+ } catch {
1731
+ return false;
1732
+ }
1733
+ }
1734
+
1598
1735
  const UPPER_RE$1 = /([A-Z])/g;
1599
1736
  const toScreamingSnake$1 = (s) => s.replace(UPPER_RE$1, "_$1").toUpperCase();
1600
1737
  const ENV_PREFIX = "NUXT_PUBLIC_SCRIPTS_";
@@ -1802,9 +1939,57 @@ function fixSelfClosingScriptComponents(nuxt) {
1802
1939
  const UPPER_RE = /([A-Z])/g;
1803
1940
  const toScreamingSnake = (s) => s.replace(UPPER_RE, "_$1").toUpperCase();
1804
1941
  const PROXY_SECRET_ENV_KEY = "NUXT_SCRIPTS_PROXY_SECRET";
1805
- const PROXY_SECRET_ENV_LINE_RE = /^NUXT_SCRIPTS_PROXY_SECRET=/m;
1942
+ const PROXY_SECRET_ENV_LINE_RE = /^NUXT_SCRIPTS_PROXY_SECRET=.*$/m;
1806
1943
  const PROXY_SECRET_ENV_VALUE_RE = /^NUXT_SCRIPTS_PROXY_SECRET=(.+)$/m;
1807
- function resolveProxySecret(rootDir, isDev, configSecret, autoGenerate = true) {
1944
+ const PROXY_SECRET_LOCK_RETRY_MS = 10;
1945
+ const PROXY_SECRET_LOCK_TIMEOUT_MS = 2e3;
1946
+ async function withProxySecretFileLock(envPath, effect) {
1947
+ const lockPath = `${envPath}.nuxt-scripts.lock`;
1948
+ const deadline = Date.now() + PROXY_SECRET_LOCK_TIMEOUT_MS;
1949
+ let lockHandle;
1950
+ while (!lockHandle) {
1951
+ const acquisition = await open(lockPath, "wx").then((handle) => ({ _tag: "Acquired", handle })).catch((error) => {
1952
+ if (error.code === "EEXIST")
1953
+ return { _tag: "Busy" };
1954
+ throw error;
1955
+ });
1956
+ if (acquisition._tag === "Acquired") {
1957
+ lockHandle = acquisition.handle;
1958
+ break;
1959
+ }
1960
+ const existingLock = await stat(lockPath).then((lockStat) => ({ _tag: "Found", mtimeMs: lockStat.mtimeMs })).catch((error) => {
1961
+ if (error.code === "ENOENT")
1962
+ return { _tag: "Missing" };
1963
+ throw error;
1964
+ });
1965
+ if (existingLock._tag === "Found" && Date.now() - existingLock.mtimeMs >= PROXY_SECRET_LOCK_TIMEOUT_MS) {
1966
+ await unlink(lockPath).catch((error) => {
1967
+ if (error.code !== "ENOENT")
1968
+ throw error;
1969
+ });
1970
+ continue;
1971
+ }
1972
+ if (Date.now() >= deadline)
1973
+ throw Object.assign(new Error("Timed out waiting for proxy secret file lock"), { code: "ETIMEDOUT" });
1974
+ await setTimeout(PROXY_SECRET_LOCK_RETRY_MS);
1975
+ }
1976
+ let effectResult;
1977
+ try {
1978
+ effectResult = { _tag: "Success", value: effect() };
1979
+ } catch (error) {
1980
+ effectResult = { _tag: "Failure", error };
1981
+ }
1982
+ const closeResult = await lockHandle.close().then(() => ({ _tag: "Success" })).catch((error) => ({ _tag: "Failure", error }));
1983
+ const unlinkResult = await unlink(lockPath).then(() => ({ _tag: "Success" })).catch((error) => error.code === "ENOENT" ? { _tag: "Success" } : { _tag: "Failure", error });
1984
+ if (closeResult._tag === "Failure")
1985
+ logger.warn(`[security] Failed to close the proxy secret lock: ${closeResult.error.message}`);
1986
+ if (unlinkResult._tag === "Failure")
1987
+ logger.warn(`[security] Failed to remove the proxy secret lock: ${unlinkResult.error.message}`);
1988
+ if (effectResult._tag === "Failure")
1989
+ throw effectResult.error;
1990
+ return effectResult.value;
1991
+ }
1992
+ async function resolveProxySecret(rootDir, isDev, configSecret, autoGenerate = true) {
1808
1993
  if (configSecret)
1809
1994
  return { secret: configSecret, ephemeral: false, source: "config" };
1810
1995
  const envSecret = process.env[PROXY_SECRET_ENV_KEY];
@@ -1817,21 +2002,26 @@ function resolveProxySecret(rootDir, isDev, configSecret, autoGenerate = true) {
1817
2002
  const line = `${PROXY_SECRET_ENV_KEY}=${secret}
1818
2003
  `;
1819
2004
  try {
1820
- if (existsSync(envPath)) {
1821
- const contents = readFileSync(envPath, "utf-8");
1822
- if (PROXY_SECRET_ENV_LINE_RE.test(contents)) {
1823
- const match = contents.match(PROXY_SECRET_ENV_VALUE_RE);
1824
- if (match?.[1])
1825
- return { secret: match[1].trim(), ephemeral: false, source: "dotenv-generated" };
1826
- }
1827
- appendFileSync(envPath, contents.endsWith("\n") ? line : `
2005
+ const persistedSecret = await withProxySecretFileLock(envPath, () => {
2006
+ if (existsSync(envPath)) {
2007
+ const contents = readFileSync(envPath, "utf-8");
2008
+ const existingSecret = contents.match(PROXY_SECRET_ENV_VALUE_RE)?.[1]?.trim();
2009
+ if (existingSecret)
2010
+ return existingSecret;
2011
+ if (PROXY_SECRET_ENV_LINE_RE.test(contents)) {
2012
+ writeFileSync(envPath, contents.replace(PROXY_SECRET_ENV_LINE_RE, `${PROXY_SECRET_ENV_KEY}=${secret}`));
2013
+ } else {
2014
+ appendFileSync(envPath, contents.endsWith("\n") ? line : `
1828
2015
  ${line}`);
1829
- } else {
1830
- writeFileSync(envPath, `# Generated by @nuxt/scripts
2016
+ }
2017
+ } else {
2018
+ writeFileSync(envPath, `# Generated by @nuxt/scripts
1831
2019
  ${line}`);
1832
- }
1833
- process.env[PROXY_SECRET_ENV_KEY] = secret;
1834
- return { secret, ephemeral: false, source: "dotenv-generated" };
2020
+ }
2021
+ return secret;
2022
+ });
2023
+ process.env[PROXY_SECRET_ENV_KEY] = persistedSecret;
2024
+ return { secret: persistedSecret, ephemeral: false, source: "dotenv-generated" };
1835
2025
  } catch {
1836
2026
  process.env[PROXY_SECRET_ENV_KEY] = secret;
1837
2027
  return { secret, ephemeral: true, source: "memory-generated" };
@@ -1874,7 +2064,10 @@ function resolveConfiguredProxyDomain(value) {
1874
2064
  if (!trimmed || !ABSOLUTE_URL_RE.test(trimmed) && !trimmed.startsWith("//"))
1875
2065
  return;
1876
2066
  try {
1877
- return new URL(trimmed, "https://nuxt-scripts.local").hostname || void 0;
2067
+ const url = new URL(trimmed, "https://nuxt-scripts.local");
2068
+ if (url.protocol !== "http:" && url.protocol !== "https:")
2069
+ return;
2070
+ return isPublicNetworkHostname(url.hostname) ? url.hostname : void 0;
1878
2071
  } catch {
1879
2072
  }
1880
2073
  }
@@ -1939,6 +2132,7 @@ const module$1 = defineNuxtModule({
1939
2132
  logger.debug("The module is disabled, skipping setup.");
1940
2133
  return;
1941
2134
  }
2135
+ await setupNitroRuntimeCompatibility(nuxt);
1942
2136
  if (nuxt.options.dev) {
1943
2137
  setupDevtools(nuxt, { standalone: config._standaloneDevtools });
1944
2138
  if (config._standaloneDevtools) {
@@ -1951,9 +2145,21 @@ const module$1 = defineNuxtModule({
1951
2145
  });
1952
2146
  }
1953
2147
  }
1954
- const { version: unheadVersion } = await readPackageJSON("@unhead/vue", {
1955
- from: nuxt.options.modulesDir
1956
- }).catch(() => ({ version: null }));
2148
+ const unheadScriptsAlias = nuxt.options.alias["@unhead/vue/scripts"];
2149
+ const unheadPackagePath = await (typeof unheadScriptsAlias === "string" ? resolvePackageJSON(unheadScriptsAlias) : Promise.reject(new Error("No Unhead scripts alias"))).catch(() => resolvePackageJSON("@unhead/vue", {
2150
+ // Match the package instance imported by the built runtime. An app can
2151
+ // contain another Unhead version with different loader capabilities.
2152
+ from: [resolveModule("./runtime")]
2153
+ })).catch(() => {
2154
+ return null;
2155
+ });
2156
+ const unheadPackage = unheadPackagePath ? await readPackageJSON(unheadPackagePath).catch(() => {
2157
+ return null;
2158
+ }) : null;
2159
+ const unheadVersion = unheadPackage?.version;
2160
+ const scriptsTypesExport = unheadPackage?.exports?.["./scripts"]?.types;
2161
+ const scriptsTypesPath = unheadPackagePath && typeof scriptsTypesExport === "string" ? resolve(dirname(unheadPackagePath), scriptsTypesExport) : null;
2162
+ const unheadSourceLessScriptLoader = hasUnheadSourceLessScriptLoaderFile(scriptsTypesPath);
1957
2163
  if (unheadVersion?.startsWith("1")) {
1958
2164
  logger.error(`Nuxt Scripts requires Unhead >= 2, you are using v${unheadVersion}. Please run \`nuxi upgrade --clean\` to upgrade...`);
1959
2165
  }
@@ -2012,10 +2218,19 @@ const module$1 = defineNuxtModule({
2012
2218
  googleStaticMapsProxy: googleMapsEnabled ? { enabled: true, cacheMaxAge: config.googleStaticMapsProxy?.cacheMaxAge ?? 3600 } : void 0
2013
2219
  };
2014
2220
  const debugConst = JSON.stringify(!!config.debug);
2221
+ const unheadSourceLessConst = JSON.stringify(unheadSourceLessScriptLoader);
2015
2222
  nuxt.options.vite ||= {};
2016
- nuxt.options.vite.define = { ...nuxt.options.vite.define, __NUXT_SCRIPTS_DEBUG__: debugConst };
2223
+ nuxt.options.vite.define = {
2224
+ ...nuxt.options.vite.define,
2225
+ __NUXT_SCRIPTS_DEBUG__: debugConst,
2226
+ __NUXT_SCRIPTS_UNHEAD_SOURCELESS__: unheadSourceLessConst
2227
+ };
2017
2228
  nuxt.options.nitro ||= {};
2018
- nuxt.options.nitro.replace = { ...nuxt.options.nitro.replace, __NUXT_SCRIPTS_DEBUG__: debugConst };
2229
+ nuxt.options.nitro.replace = {
2230
+ ...nuxt.options.nitro.replace,
2231
+ __NUXT_SCRIPTS_DEBUG__: debugConst,
2232
+ __NUXT_SCRIPTS_UNHEAD_SOURCELESS__: unheadSourceLessConst
2233
+ };
2019
2234
  const scriptsBase = config.prefix || "/_scripts";
2020
2235
  const proxyPrefix = `${scriptsBase}/p`;
2021
2236
  const assetsPrefix = `${scriptsBase}/assets`;
@@ -2369,6 +2584,7 @@ Options: configure platform rewrites, switch to server-rendered mode, or disable
2369
2584
  );
2370
2585
  }
2371
2586
  }
2587
+ ensureNuxtScriptsCacheStorage(nuxt.options.nitro);
2372
2588
  nuxt.options.runtimeConfig.public["nuxt-scripts"] = defu(
2373
2589
  { endpoints: enabledEndpoints },
2374
2590
  nuxt.options.runtimeConfig.public["nuxt-scripts"]
@@ -2388,7 +2604,7 @@ Options: configure platform rewrites, switch to server-rendered mode, or disable
2388
2604
  To enable signing, deploy with a server-rendered target or configure platform-level rewrites.`
2389
2605
  );
2390
2606
  } else if (anyHandlerRequiresSigning) {
2391
- const proxySecretResolved = resolveProxySecret(
2607
+ const proxySecretResolved = await resolveProxySecret(
2392
2608
  nuxt.options.rootDir,
2393
2609
  !!nuxt.options.dev,
2394
2610
  config.security?.secret,
package/dist/registry.mjs CHANGED
@@ -808,8 +808,8 @@ async function registry(resolve) {
808
808
  }
809
809
  function generatePartytownResolveUrl(proxyPrefix, domainAliases = {}) {
810
810
  return `function(url, location, type) {
811
- if (url.origin !== location.origin) {
812
- var aliases = ${JSON.stringify(domainAliases)};
811
+ if ((url.protocol === 'http:' || url.protocol === 'https:') && url.origin !== location.origin) {
812
+ var aliases = Object.assign(Object.create(null), ${JSON.stringify(domainAliases)});
813
813
  var seg = aliases[url.host] || url.host;
814
814
  return new URL(${JSON.stringify(proxyPrefix)} + '/' + seg + url.pathname + url.search, location.origin);
815
815
  }