@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/client/200.html +1 -1
- package/dist/client/404.html +1 -1
- package/dist/client/_nuxt/{6CwTUC2b.js → CxpRPAAJ.js} +1 -1
- package/dist/client/_nuxt/{B71AlSZ1.js → D0d_xOOu.js} +1 -1
- package/dist/client/_nuxt/{BYGJV5dd.js → DxzaVa0B.js} +1 -1
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/d7ecb215-eee2-4720-b2bc-f3ad271b9c30.json +1 -0
- package/dist/client/_nuxt/entry.esAfLJmC.css +1 -0
- package/dist/client/_nuxt/ojT6Btul.js +162 -0
- package/dist/client/index.html +1 -1
- package/dist/module.d.mts +22 -44
- package/dist/module.d.ts +22 -44
- package/dist/module.json +1 -1
- package/dist/module.mjs +204 -163
- package/dist/registry.d.mts +6 -1
- package/dist/registry.d.ts +6 -1
- package/dist/registry.mjs +145 -6
- package/dist/runtime/registry/gravatar.d.ts +1 -1
- package/dist/runtime/server/proxy-handler.js +0 -1
- package/dist/runtime/server/utils/privacy.d.ts +0 -8
- package/dist/runtime/server/utils/privacy.js +7 -7
- package/dist/runtime/types.d.ts +71 -13
- package/dist/shared/scripts.T4Z99VT8.mjs +37 -0
- package/dist/stats.mjs +3 -3
- package/dist/types-source.mjs +1 -1
- package/dist/types.d.mts +1 -1
- package/package.json +2 -2
- package/dist/client/_nuxt/V4W-T8W6.js +0 -162
- package/dist/client/_nuxt/builds/meta/70b59a3e-a025-4a77-a25a-dfadf5b1749d.json +0 -1
- package/dist/client/_nuxt/entry.C5SUNdim.css +0 -1
- package/dist/shared/scripts.D7e2ENu6.mjs +0 -211
package/dist/module.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
2
|
-
import {
|
|
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 {
|
|
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) =>
|
|
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
|
|
92
|
-
const proxyPrefix = typeof config.
|
|
93
|
-
const privacy = typeof config.
|
|
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
|
|
96
|
-
|
|
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?.
|
|
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 {
|
|
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.
|
|
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?.
|
|
290
|
+
if (entryScriptOptions?.reverseProxyIntercept === false || entryInput?.reverseProxyIntercept === false)
|
|
159
291
|
continue;
|
|
160
|
-
const configKey = script.
|
|
292
|
+
const configKey = script.proxyConfig || key;
|
|
161
293
|
const proxyConfig = proxyConfigs[configKey];
|
|
162
294
|
if (!proxyConfig) {
|
|
163
|
-
|
|
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
|
|
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
|
|
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
|
|
1008
|
-
return prop.type === "Property" && prop.key?.name === "
|
|
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 =
|
|
1041
|
+
let firstPartyOptOut = rpiOption?.value.value === false;
|
|
1011
1042
|
if (!firstPartyOptOut && node.arguments[1]?.type === "ObjectExpression") {
|
|
1012
|
-
const
|
|
1013
|
-
(p) => p.type === "Property" && p.key?.name === "
|
|
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 =
|
|
1046
|
+
firstPartyOptOut = secondArgProp?.value.value === false;
|
|
1016
1047
|
}
|
|
1017
1048
|
if (!firstPartyOptOut && node.arguments[0]?.type === "ObjectExpression") {
|
|
1018
|
-
const
|
|
1019
|
-
(p) => p.type === "Property" && p.key?.name === "
|
|
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 =
|
|
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
|
|
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.
|
|
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 (
|
|
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
|
|
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
|
|
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));
|
package/dist/registry.d.mts
CHANGED
|
@@ -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 };
|
package/dist/registry.d.ts
CHANGED
|
@@ -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 };
|