@nuxt/scripts 1.0.0-beta.30 → 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.
Files changed (37) hide show
  1. package/dist/client/200.html +1 -1
  2. package/dist/client/404.html +1 -1
  3. package/dist/client/_nuxt/{CYlYSSNW.js → CxpRPAAJ.js} +1 -1
  4. package/dist/client/_nuxt/{D5FIkDae.js → D0d_xOOu.js} +1 -1
  5. package/dist/client/_nuxt/{AwAKM0sG.js → DxzaVa0B.js} +1 -1
  6. package/dist/client/_nuxt/builds/latest.json +1 -1
  7. package/dist/client/_nuxt/builds/meta/d7ecb215-eee2-4720-b2bc-f3ad271b9c30.json +1 -0
  8. package/dist/client/_nuxt/entry.esAfLJmC.css +1 -0
  9. package/dist/client/_nuxt/ojT6Btul.js +162 -0
  10. package/dist/client/index.html +1 -1
  11. package/dist/module.d.mts +23 -45
  12. package/dist/module.d.ts +23 -45
  13. package/dist/module.json +1 -1
  14. package/dist/module.mjs +241 -227
  15. package/dist/registry.d.mts +6 -1
  16. package/dist/registry.d.ts +6 -1
  17. package/dist/registry.mjs +150 -11
  18. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.d.vue.ts +5 -2
  19. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue +11 -2
  20. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue.d.ts +5 -2
  21. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.d.vue.ts +14 -0
  22. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.vue +50 -1
  23. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.vue.d.ts +14 -0
  24. package/dist/runtime/registry/gravatar.d.ts +1 -1
  25. package/dist/runtime/server/proxy-handler.js +25 -36
  26. package/dist/runtime/server/utils/privacy.d.ts +0 -8
  27. package/dist/runtime/server/utils/privacy.js +7 -7
  28. package/dist/runtime/types.d.ts +71 -13
  29. package/dist/shared/scripts.T4Z99VT8.mjs +37 -0
  30. package/dist/stats.mjs +7 -15
  31. package/dist/types-source.mjs +16 -2
  32. package/dist/types.d.mts +1 -1
  33. package/package.json +2 -2
  34. package/dist/client/_nuxt/Bl23o3st.js +0 -162
  35. package/dist/client/_nuxt/builds/meta/f0b4dd20-8496-4003-b7a3-05cbae515923.json +0 -1
  36. package/dist/client/_nuxt/entry.C5SUNdim.css +0 -1
  37. package/dist/shared/scripts.ViOoYQXH.mjs +0 -381
@@ -11,18 +11,8 @@ import {
11
11
  stripPayloadFingerprinting
12
12
  } from "./utils/privacy.js";
13
13
  const COMPRESSION_RE = /gzip|deflate|br|compress|base64/i;
14
- const ROUTE_WILDCARD_RE = /\/\*\*$/;
15
14
  const CLIENT_HINT_VERSION_RE = /;v="(\d+)\.[^"]*"/g;
16
15
  const SKIP_RESPONSE_HEADERS = /* @__PURE__ */ new Set(["set-cookie", "transfer-encoding", "content-encoding", "content-length"]);
17
- let sortedRoutesCache;
18
- function getSortedRoutes(routes) {
19
- const key = JSON.stringify(routes);
20
- if (sortedRoutesCache?.key === key)
21
- return sortedRoutesCache.sorted;
22
- const sorted = Object.entries(routes).sort((a, b) => b[0].length - a[0].length);
23
- sortedRoutesCache = { key, sorted };
24
- return sorted;
25
- }
26
16
  function stripQueryFingerprinting(query, privacy) {
27
17
  const stripped = stripPayloadFingerprinting(query, privacy);
28
18
  const params = new URLSearchParams();
@@ -42,37 +32,41 @@ export default defineEventHandler(async (event) => {
42
32
  statusMessage: "First-party proxy not configured"
43
33
  });
44
34
  }
45
- const { routes, privacy: globalPrivacy, routePrivacy, debug = import.meta.dev } = proxyConfig;
35
+ const { proxyPrefix, domainPrivacy, privacy: globalPrivacy, debug = import.meta.dev } = proxyConfig;
46
36
  const path = event.path;
47
37
  const log = debug ? (message, ...args) => {
48
38
  console.debug(message, ...args);
49
39
  } : () => {
50
40
  };
51
- let targetBase;
52
- let matchedPrefix;
53
- let matchedRoutePattern;
54
- for (const [routePattern, target] of getSortedRoutes(routes)) {
55
- const prefix = routePattern.replace(ROUTE_WILDCARD_RE, "");
56
- if (path.startsWith(prefix)) {
57
- targetBase = target.replace(ROUTE_WILDCARD_RE, "");
58
- matchedPrefix = prefix;
59
- matchedRoutePattern = routePattern;
60
- log("[proxy] Matched:", prefix, "->", targetBase);
41
+ const afterPrefix = path.slice(proxyPrefix.length + 1);
42
+ const slashIdx = afterPrefix.indexOf("/");
43
+ const domain = slashIdx > 0 ? afterPrefix.slice(0, slashIdx) : afterPrefix;
44
+ const remainingPath = slashIdx > 0 ? afterPrefix.slice(slashIdx) : "/";
45
+ if (!domain) {
46
+ log("[proxy] No domain in path:", path);
47
+ throw createError({
48
+ statusCode: 404,
49
+ statusMessage: "No proxy domain found",
50
+ message: `No domain in proxy path: ${path}`
51
+ });
52
+ }
53
+ let perScriptInput;
54
+ for (const [configDomain, privacyInput] of Object.entries(domainPrivacy)) {
55
+ if (domain === configDomain || domain.endsWith(`.${configDomain}`)) {
56
+ perScriptInput = privacyInput;
61
57
  break;
62
58
  }
63
59
  }
64
- if (!targetBase || !matchedPrefix || !matchedRoutePattern) {
65
- log("[proxy] No match for path:", path);
60
+ if (perScriptInput === void 0) {
61
+ log("[proxy] Rejected: domain not in allowlist:", domain);
66
62
  throw createError({
67
- statusCode: 404,
68
- statusMessage: "No proxy route matched",
69
- message: `No proxy target found for path: ${path}`
63
+ statusCode: 403,
64
+ statusMessage: "Domain not allowed",
65
+ message: `Proxy domain not in allowlist: ${domain}`
70
66
  });
71
67
  }
72
- const perScriptInput = routePrivacy[matchedRoutePattern];
73
- if (debug && perScriptInput === void 0) {
74
- log("[proxy] WARNING: No privacy config for route", matchedRoutePattern, "\u2014 defaulting to full anonymization");
75
- }
68
+ const targetBase = `https://${domain}`;
69
+ log("[proxy] Matched:", domain, "->", targetBase);
76
70
  const perScriptResolved = resolvePrivacy(perScriptInput ?? true);
77
71
  const privacy = globalPrivacy !== void 0 ? mergePrivacy(perScriptResolved, globalPrivacy) : perScriptResolved;
78
72
  const anyPrivacy = privacy.ip || privacy.userAgent || privacy.language || privacy.screen || privacy.timezone || privacy.hardware;
@@ -83,11 +77,7 @@ export default defineEventHandler(async (event) => {
83
77
  const isBinaryBody = Boolean(
84
78
  originalHeaders["content-encoding"] || contentType.includes("octet-stream") || compressionParam && COMPRESSION_RE.test(compressionParam)
85
79
  );
86
- let targetPath = path.slice(matchedPrefix.length);
87
- if (targetPath && !targetPath.startsWith("/")) {
88
- targetPath = `/${targetPath}`;
89
- }
90
- let targetUrl = targetBase + targetPath;
80
+ let targetUrl = targetBase + remainingPath;
91
81
  let strippedQueryRecord;
92
82
  if (anyPrivacy) {
93
83
  if (Object.keys(originalQuery).length > 0) {
@@ -260,7 +250,6 @@ export default defineEventHandler(async (event) => {
260
250
  duplex: passthroughBody ? "half" : void 0
261
251
  });
262
252
  } catch (err) {
263
- clearTimeout(timeoutId);
264
253
  log("[proxy] Upstream error:", err);
265
254
  throw createError({
266
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.ViOoYQXH.mjs';
1
+ import { b as buildProxyConfigsFromRegistry } from './shared/scripts.T4Z99VT8.mjs';
2
2
 
3
3
  const scriptMeta = {
4
4
  // Analytics
@@ -3767,7 +3767,6 @@ function computePerformanceRating(perf, transferKb, network, cwv) {
3767
3767
  }
3768
3768
  };
3769
3769
  }
3770
- const DOMAIN_RE = /^https?:\/\/([^/]+)/;
3771
3770
  const USE_SCRIPT_RE = /^useScript/;
3772
3771
  const WORD_SPLIT_RE = /[\s-]+/;
3773
3772
  function computePrivacyLevel(privacy) {
@@ -3780,14 +3779,8 @@ function computePrivacyLevel(privacy) {
3780
3779
  return "partial";
3781
3780
  return "none";
3782
3781
  }
3783
- function extractDomains(routes) {
3784
- const domains = /* @__PURE__ */ new Set();
3785
- for (const { proxy } of Object.values(routes)) {
3786
- const match = proxy.match(DOMAIN_RE);
3787
- if (match?.[1])
3788
- domains.add(match[1]);
3789
- }
3790
- return [...domains].sort();
3782
+ function extractDomains(proxyDomains) {
3783
+ return [...proxyDomains].sort();
3791
3784
  }
3792
3785
  function deriveMetaKey(importName, label) {
3793
3786
  if (importName) {
@@ -3805,13 +3798,13 @@ function deriveMetaKey(importName, label) {
3805
3798
  async function getScriptStats() {
3806
3799
  const { registry } = await import('./registry.mjs');
3807
3800
  const entries = await registry();
3808
- const proxyConfigs = getAllProxyConfigs("/_scripts/p");
3801
+ const proxyConfigs = buildProxyConfigsFromRegistry(entries);
3809
3802
  const sizes = scriptSizes;
3810
3803
  return entries.map((entry) => {
3811
3804
  const id = entry.registryKey || deriveMetaKey(entry.import?.name, entry.label);
3812
3805
  const meta = id && id in scriptMeta ? scriptMeta[id] : void 0;
3813
3806
  const size = sizes[id || ""];
3814
- const proxyConfigKey = entry.proxy === false ? void 0 : entry.proxy || entry.registryKey;
3807
+ const proxyConfigKey = !entry.capabilities?.reverseProxyIntercept ? void 0 : entry.proxyConfig || entry.registryKey;
3815
3808
  const proxyConfig = proxyConfigKey ? proxyConfigs[proxyConfigKey] : void 0;
3816
3809
  let loadingMethod = "cdn";
3817
3810
  if (entry.src === false)
@@ -3819,9 +3812,8 @@ async function getScriptStats() {
3819
3812
  else if (!entry.src && typeof entry.scriptBundling === "function")
3820
3813
  loadingMethod = "dynamic";
3821
3814
  const privacy = proxyConfig?.privacy ?? null;
3822
- const routes = proxyConfig?.routes ?? {};
3823
- const domains = extractDomains(routes);
3824
- const endpoints = Object.keys(routes).length;
3815
+ const domains = extractDomains(proxyConfig?.domains ?? []);
3816
+ const endpoints = domains.length;
3825
3817
  const emptyApis = {};
3826
3818
  const emptyNetwork = { requestCount: 0, domains: [], outboundBytes: 0, inboundBytes: 0, injectedElements: [] };
3827
3819
  const emptyPerf = { taskDurationMs: 0, scriptDurationMs: 0, heapDeltaKb: 0 };
@@ -276,7 +276,7 @@ const types = {
276
276
  {
277
277
  name: "ScriptGoogleMapsOverlayViewProps",
278
278
  kind: "interface",
279
- code: "interface ScriptGoogleMapsOverlayViewProps {\n /**\n * Geographic position for the overlay. Falls back to parent marker position if omitted.\n * @see https://developers.google.com/maps/documentation/javascript/reference/overlay-view#OverlayView\n */\n position?: google.maps.LatLngLiteral\n /**\n * Anchor point of the overlay relative to its position.\n * @default 'bottom-center'\n */\n anchor?: OverlayAnchor\n /**\n * Pixel offset from the anchor position.\n */\n offset?: { x: number, y: number }\n /**\n * The map pane on which to render the overlay.\n * @default 'floatPane'\n * @see https://developers.google.com/maps/documentation/javascript/reference/overlay-view#MapPanes\n */\n pane?: OverlayPane\n /**\n * CSS z-index for the overlay element.\n */\n zIndex?: number\n /**\n * Whether to block map click and gesture events from passing through the overlay.\n * @default true\n */\n blockMapInteraction?: boolean\n}"
279
+ code: "interface ScriptGoogleMapsOverlayViewProps {\n /**\n * Geographic position for the overlay. Falls back to parent marker position if omitted.\n * @see https://developers.google.com/maps/documentation/javascript/reference/overlay-view#OverlayView\n */\n position?: google.maps.LatLngLiteral\n /**\n * Anchor point of the overlay relative to its position.\n * @default 'bottom-center'\n */\n anchor?: OverlayAnchor\n /**\n * Pixel offset from the anchor position.\n */\n offset?: { x: number, y: number }\n /**\n * The map pane on which to render the overlay.\n * @default 'floatPane'\n * @see https://developers.google.com/maps/documentation/javascript/reference/overlay-view#MapPanes\n */\n pane?: OverlayPane\n /**\n * CSS z-index for the overlay element.\n */\n zIndex?: number\n /**\n * Whether to block map click and gesture events from passing through the overlay.\n * @default true\n */\n blockMapInteraction?: boolean\n /**\n * Pan the map so the overlay is fully visible when opened, similar to InfoWindow behavior.\n * Set to `true` for default 40px padding, or a number for custom padding.\n * @default true\n */\n panOnOpen?: boolean | number\n /**\n * Automatically hide the overlay when its parent marker joins a cluster (on zoom out).\n * Only applies when nested inside a ScriptGoogleMapsMarkerClusterer.\n * @default true\n */\n hideWhenClustered?: boolean\n}"
280
280
  },
281
281
  {
282
282
  name: "ScriptGoogleMapsPinElementProps",
@@ -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: [
@@ -2697,6 +2697,20 @@ const schemaFields = {
2697
2697
  description: "Whether to block map click and gesture events from passing through the overlay.",
2698
2698
  defaultValue: "true"
2699
2699
  },
2700
+ {
2701
+ name: "panOnOpen",
2702
+ type: "boolean | number",
2703
+ required: false,
2704
+ description: "Pan the map so the overlay is fully visible when opened, similar to InfoWindow behavior. Set to `true` for default 40px padding, or a number for custom padding.",
2705
+ defaultValue: "true"
2706
+ },
2707
+ {
2708
+ name: "hideWhenClustered",
2709
+ type: "boolean",
2710
+ required: false,
2711
+ description: "Automatically hide the overlay when its parent marker joins a cluster (on zoom out). Only applies when nested inside a ScriptGoogleMapsMarkerClusterer.",
2712
+ defaultValue: "true"
2713
+ },
2700
2714
  {
2701
2715
  name: "v-model:open",
2702
2716
  type: "boolean",
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.30",
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.30"
147
+ "@nuxt/scripts": "1.0.0-beta.32"
148
148
  },
149
149
  "resolutions": {
150
150
  "@nuxt/scripts": "workspace:*"