@nuxt/scripts 1.0.0-rc.1 → 1.0.0-rc.10
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/bin/cli.mjs +2 -0
- package/dist/cli.d.mts +2 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.mjs +50 -0
- package/dist/devtools-client/200.html +1 -1
- package/dist/devtools-client/404.html +1 -1
- package/dist/devtools-client/_nuxt/{ajngqPCs.js → BgPDxVUn.js} +1 -1
- package/dist/devtools-client/_nuxt/{DKL6PHO3.js → BmlapxLP.js} +1 -1
- package/dist/devtools-client/_nuxt/CM2vefXI.js +188 -0
- package/dist/devtools-client/_nuxt/{CfOsp0mU.js → DAF5Qk9P.js} +1 -1
- package/dist/devtools-client/_nuxt/{B3kN3DAy.js → Dx6HhVmj.js} +1 -1
- package/dist/devtools-client/_nuxt/{dlaR8P-P.js → S8LiR9M1.js} +1 -1
- package/dist/devtools-client/_nuxt/builds/latest.json +1 -1
- package/dist/devtools-client/_nuxt/builds/meta/5458a3f2-af35-479c-8852-bf6f92fed611.json +1 -0
- package/dist/devtools-client/_nuxt/{entry.BwpOBArY.css → entry.BKkVrcJj.css} +1 -1
- package/dist/devtools-client/_nuxt/error-404.d44aGwWI.css +1 -0
- package/dist/devtools-client/_nuxt/error-500.NthMfIEt.css +1 -0
- package/dist/devtools-client/_nuxt/index.DZD1lwyI.css +1 -0
- package/dist/devtools-client/_nuxt/vBkR1GJq.js +1 -0
- package/dist/devtools-client/docs/index.html +1 -1
- package/dist/devtools-client/first-party/index.html +1 -1
- package/dist/devtools-client/index.html +1 -1
- package/dist/devtools-client/registry/index.html +1 -1
- package/dist/module.d.mts +66 -2
- package/dist/module.d.ts +66 -2
- package/dist/module.json +1 -1
- package/dist/module.mjs +144 -28
- package/dist/registry.d.mts +1 -0
- package/dist/registry.d.ts +1 -0
- package/dist/registry.mjs +14 -14
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.d.vue.ts +73 -97
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue +81 -58
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue.d.ts +73 -97
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.d.vue.ts +2 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.vue +1 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.vue.d.ts +2 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.d.vue.ts +2 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue +2 -1
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue.d.ts +2 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.d.vue.ts +10 -43
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue +3 -1
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue.d.ts +10 -43
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.d.vue.ts +50 -30
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.vue +145 -104
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.vue.d.ts +50 -30
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsStaticMap.vue +7 -2
- package/dist/runtime/components/GoogleMaps/types.d.ts +42 -0
- package/dist/runtime/components/GoogleMaps/types.js +1 -0
- package/dist/runtime/components/GoogleMaps/useGoogleMapsResource.d.ts +50 -0
- package/dist/runtime/components/GoogleMaps/useGoogleMapsResource.js +76 -1
- package/dist/runtime/components/ScriptBlueskyEmbed.d.vue.ts +10 -12
- package/dist/runtime/components/ScriptBlueskyEmbed.vue +13 -10
- package/dist/runtime/components/ScriptBlueskyEmbed.vue.d.ts +10 -12
- package/dist/runtime/components/ScriptCarbonAds.d.vue.ts +4 -7
- package/dist/runtime/components/ScriptCarbonAds.vue +1 -0
- package/dist/runtime/components/ScriptCarbonAds.vue.d.ts +4 -7
- package/dist/runtime/components/ScriptCrisp.d.vue.ts +7 -11
- package/dist/runtime/components/ScriptCrisp.vue +1 -0
- package/dist/runtime/components/ScriptCrisp.vue.d.ts +7 -11
- package/dist/runtime/components/ScriptGoogleAdsense.d.vue.ts +4 -7
- package/dist/runtime/components/ScriptGoogleAdsense.vue +1 -0
- package/dist/runtime/components/ScriptGoogleAdsense.vue.d.ts +4 -7
- package/dist/runtime/components/ScriptInstagramEmbed.d.vue.ts +11 -13
- package/dist/runtime/components/ScriptInstagramEmbed.vue +4 -1
- package/dist/runtime/components/ScriptInstagramEmbed.vue.d.ts +11 -13
- package/dist/runtime/components/ScriptIntercom.d.vue.ts +7 -11
- package/dist/runtime/components/ScriptIntercom.vue +1 -0
- package/dist/runtime/components/ScriptIntercom.vue.d.ts +7 -11
- package/dist/runtime/components/ScriptLemonSqueezy.d.vue.ts +2 -3
- package/dist/runtime/components/ScriptLemonSqueezy.vue +1 -0
- package/dist/runtime/components/ScriptLemonSqueezy.vue.d.ts +2 -3
- package/dist/runtime/components/ScriptPayPalButtons.d.vue.ts +8 -13
- package/dist/runtime/components/ScriptPayPalButtons.vue +1 -0
- package/dist/runtime/components/ScriptPayPalButtons.vue.d.ts +8 -13
- package/dist/runtime/components/ScriptPayPalMessages.d.vue.ts +8 -13
- package/dist/runtime/components/ScriptPayPalMessages.vue +1 -0
- package/dist/runtime/components/ScriptPayPalMessages.vue.d.ts +8 -13
- package/dist/runtime/components/ScriptStripePricingTable.d.vue.ts +5 -9
- package/dist/runtime/components/ScriptStripePricingTable.vue +1 -0
- package/dist/runtime/components/ScriptStripePricingTable.vue.d.ts +5 -9
- package/dist/runtime/components/ScriptVimeoPlayer.d.vue.ts +8 -11
- package/dist/runtime/components/ScriptVimeoPlayer.vue +1 -0
- package/dist/runtime/components/ScriptVimeoPlayer.vue.d.ts +8 -11
- package/dist/runtime/components/ScriptXEmbed.d.vue.ts +10 -12
- package/dist/runtime/components/ScriptXEmbed.vue +12 -9
- package/dist/runtime/components/ScriptXEmbed.vue.d.ts +10 -12
- package/dist/runtime/components/ScriptYouTubePlayer.d.vue.ts +8 -13
- package/dist/runtime/components/ScriptYouTubePlayer.vue +1 -0
- package/dist/runtime/components/ScriptYouTubePlayer.vue.d.ts +8 -13
- package/dist/runtime/composables/useScript.js +17 -6
- package/dist/runtime/composables/useScriptProxyToken.d.ts +12 -0
- package/dist/runtime/composables/useScriptProxyToken.js +4 -0
- package/dist/runtime/composables/useScriptProxyUrl.d.ts +12 -0
- package/dist/runtime/composables/useScriptProxyUrl.js +27 -0
- package/dist/runtime/plugins/proxy-token.server.d.ts +10 -0
- package/dist/runtime/plugins/proxy-token.server.js +17 -0
- package/dist/runtime/registry/bing-uet.d.ts +189 -11
- package/dist/runtime/registry/bing-uet.js +16 -2
- package/dist/runtime/registry/bluesky-embed.d.ts +0 -4
- package/dist/runtime/registry/bluesky-embed.js +0 -4
- package/dist/runtime/registry/clarity.d.ts +6 -2
- package/dist/runtime/registry/clarity.js +12 -1
- package/dist/runtime/registry/google-analytics.d.ts +6 -2
- package/dist/runtime/registry/google-analytics.js +12 -1
- package/dist/runtime/registry/google-tag-manager.d.ts +6 -2
- package/dist/runtime/registry/google-tag-manager.js +10 -1
- package/dist/runtime/registry/gravatar.js +10 -13
- package/dist/runtime/registry/matomo-analytics.d.ts +9 -3
- package/dist/runtime/registry/matomo-analytics.js +28 -1
- package/dist/runtime/registry/meta-pixel.d.ts +8 -2
- package/dist/runtime/registry/meta-pixel.js +10 -1
- package/dist/runtime/registry/mixpanel-analytics.d.ts +12 -2
- package/dist/runtime/registry/mixpanel-analytics.js +16 -4
- package/dist/runtime/registry/posthog.d.ts +8 -2
- package/dist/runtime/registry/posthog.js +15 -4
- package/dist/runtime/registry/schemas.d.ts +65 -0
- package/dist/runtime/registry/schemas.js +75 -8
- package/dist/runtime/registry/tiktok-pixel.d.ts +16 -2
- package/dist/runtime/registry/tiktok-pixel.js +22 -1
- package/dist/runtime/registry/x-embed.d.ts +0 -4
- package/dist/runtime/registry/x-embed.js +0 -4
- package/dist/runtime/server/bluesky-embed-image.d.ts +1 -1
- package/dist/runtime/server/bluesky-embed.d.ts +1 -15
- package/dist/runtime/server/bluesky-embed.js +25 -6
- package/dist/runtime/server/google-maps-geocode-proxy.js +12 -8
- package/dist/runtime/server/google-static-maps-proxy.d.ts +1 -1
- package/dist/runtime/server/google-static-maps-proxy.js +17 -11
- package/dist/runtime/server/gravatar-proxy.d.ts +1 -1
- package/dist/runtime/server/gravatar-proxy.js +10 -10
- package/dist/runtime/server/instagram-embed-asset.d.ts +1 -1
- package/dist/runtime/server/instagram-embed-image.d.ts +1 -1
- package/dist/runtime/server/instagram-embed.d.ts +1 -16
- package/dist/runtime/server/instagram-embed.js +26 -125
- package/dist/runtime/server/proxy-handler.js +1 -2
- package/dist/runtime/server/utils/cached-upstream.d.ts +55 -0
- package/dist/runtime/server/utils/cached-upstream.js +65 -0
- package/dist/runtime/server/utils/embed-rewriters.d.ts +19 -0
- package/dist/runtime/server/utils/embed-rewriters.js +41 -0
- package/dist/runtime/server/utils/image-proxy.d.ts +3 -1
- package/dist/runtime/server/utils/image-proxy.js +11 -8
- package/dist/runtime/server/utils/instagram-embed.d.ts +16 -0
- package/dist/runtime/server/utils/instagram-embed.js +153 -0
- package/dist/runtime/server/utils/proxy-url.d.ts +9 -0
- package/dist/runtime/server/utils/proxy-url.js +21 -0
- package/dist/runtime/server/utils/sign-constants.d.ts +16 -0
- package/dist/runtime/server/utils/sign-constants.js +5 -0
- package/dist/runtime/server/utils/sign.d.ts +101 -0
- package/dist/runtime/server/utils/sign.js +91 -0
- package/dist/runtime/server/utils/withSigning.d.ts +23 -0
- package/dist/runtime/server/utils/withSigning.js +19 -0
- package/dist/runtime/server/x-embed-image.d.ts +1 -1
- package/dist/runtime/server/x-embed.js +23 -4
- package/dist/runtime/types.d.ts +41 -6
- package/dist/runtime/types.js +1 -0
- package/dist/stats.mjs +298 -338
- package/dist/types-source.mjs +537 -164
- package/dist/types.d.mts +2 -2
- package/package.json +10 -6
- package/dist/devtools-client/_nuxt/C8jhSQ8l.js +0 -1
- package/dist/devtools-client/_nuxt/CJD6wrkT.js +0 -188
- package/dist/devtools-client/_nuxt/builds/meta/b800a0be-5cab-4ea6-89e3-dd3a85690a73.json +0 -1
- package/dist/devtools-client/_nuxt/error-404.CvOVjXeC.css +0 -1
- package/dist/devtools-client/_nuxt/error-500.BIm53nmx.css +0 -1
- package/dist/devtools-client/_nuxt/index.CA-OpSj0.css +0 -1
package/dist/module.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
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';
|
|
3
4
|
import { defu } from 'defu';
|
|
4
5
|
import { join, resolve } from 'pathe';
|
|
5
6
|
import { resolvePackageJSON, readPackageJSON } from 'pkg-types';
|
|
@@ -12,7 +13,6 @@ import { isCI, provider } from 'std-env';
|
|
|
12
13
|
import { parseAndWalk, ScopeTracker, walk, ScopeTrackerFunction, ScopeTrackerIdentifier, ScopeTrackerFunctionParam, ScopeTrackerVariable } from 'oxc-walker';
|
|
13
14
|
import { createUnplugin } from 'unplugin';
|
|
14
15
|
import { pathToFileURL } from 'node:url';
|
|
15
|
-
import { createHash } from 'node:crypto';
|
|
16
16
|
import fsp from 'node:fs/promises';
|
|
17
17
|
import { colors } from 'consola/utils';
|
|
18
18
|
import MagicString from 'magic-string';
|
|
@@ -416,7 +416,8 @@ function NuxtScriptsCheckScripts() {
|
|
|
416
416
|
});
|
|
417
417
|
}
|
|
418
418
|
|
|
419
|
-
function generateInterceptPluginContents(proxyPrefix) {
|
|
419
|
+
function generateInterceptPluginContents(proxyPrefix, options) {
|
|
420
|
+
const testMode = options?.testMode ?? false;
|
|
420
421
|
return `export default defineNuxtPlugin({
|
|
421
422
|
name: 'nuxt-scripts:intercept',
|
|
422
423
|
enforce: 'pre',
|
|
@@ -461,8 +462,14 @@ function generateInterceptPluginContents(proxyPrefix) {
|
|
|
461
462
|
return img;
|
|
462
463
|
}
|
|
463
464
|
|
|
464
|
-
globalThis.__nuxtScripts = {
|
|
465
|
-
|
|
465
|
+
globalThis.__nuxtScripts = {${testMode ? `
|
|
466
|
+
// Test mode: replace sendBeacon with fetch for immediate, observable requests
|
|
467
|
+
sendBeacon: (url, data) => {
|
|
468
|
+
const proxied = proxyUrl(url);
|
|
469
|
+
origFetch(proxied, { method: 'POST', body: data, keepalive: true }).catch(() => {});
|
|
470
|
+
return true;
|
|
471
|
+
},` : `
|
|
472
|
+
sendBeacon: (url, data) => origBeacon(proxyUrl(url), data),`}
|
|
466
473
|
fetch: (url, opts) => {
|
|
467
474
|
if (typeof url === 'string') return origFetch(proxyUrl(url), opts);
|
|
468
475
|
if (url instanceof Request) return origFetch(new Request(proxyUrl(url.url), url), opts);
|
|
@@ -908,6 +915,7 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
908
915
|
const node = _node;
|
|
909
916
|
let scriptSrcNode;
|
|
910
917
|
let src;
|
|
918
|
+
let registryConfig = {};
|
|
911
919
|
let registryKey;
|
|
912
920
|
if (fnName !== "useScript") {
|
|
913
921
|
const baseName = fnName.replace(USE_SCRIPT_RE, "");
|
|
@@ -930,7 +938,7 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
930
938
|
const bundleResolve = getBundleResolve(registryNode);
|
|
931
939
|
if (!bundleResolve && !registryNode.src)
|
|
932
940
|
return;
|
|
933
|
-
|
|
941
|
+
registryConfig = options.registryConfig?.[registryKey || ""] || {};
|
|
934
942
|
const fnArg0 = {};
|
|
935
943
|
if (node.arguments[0]?.type === "ObjectExpression") {
|
|
936
944
|
const optionsNode = node.arguments[0];
|
|
@@ -978,12 +986,14 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
978
986
|
const registryScript = fnName !== "useScript" ? options.scripts?.find((s2) => s2.import.name === fnName) : void 0;
|
|
979
987
|
let canBundle = !!registryScript?.bundle;
|
|
980
988
|
let forceDownload = false;
|
|
989
|
+
let explicitBundleInCall = false;
|
|
981
990
|
if (node.arguments[1]?.type === "ObjectExpression") {
|
|
982
991
|
const scriptOptionsArg = node.arguments[1];
|
|
983
992
|
const bundleProperty = scriptOptionsArg.properties.find(
|
|
984
993
|
(p) => (p.key?.name === "bundle" || p.key?.value === "bundle") && p.type === "Property"
|
|
985
994
|
);
|
|
986
995
|
if (bundleProperty && bundleProperty.value.type === "Literal") {
|
|
996
|
+
explicitBundleInCall = true;
|
|
987
997
|
const bundleValue = bundleProperty.value.value;
|
|
988
998
|
if (bundleValue !== true && bundleValue !== "force" && String(bundleValue) !== "true") {
|
|
989
999
|
canBundle = false;
|
|
@@ -1008,10 +1018,16 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
1008
1018
|
return prop.type === "Property" && prop.key?.name === "bundle" && prop.value.type === "Literal";
|
|
1009
1019
|
});
|
|
1010
1020
|
if (bundleOption) {
|
|
1021
|
+
explicitBundleInCall = true;
|
|
1011
1022
|
const bundleValue = bundleOption.value.value;
|
|
1012
1023
|
canBundle = bundleValue === true || bundleValue === "force" || String(bundleValue) === "true";
|
|
1013
1024
|
forceDownload = bundleValue === "force";
|
|
1014
1025
|
}
|
|
1026
|
+
if (!explicitBundleInCall && registryConfig?.scriptOptions?.bundle !== void 0) {
|
|
1027
|
+
const bundleValue = registryConfig.scriptOptions.bundle;
|
|
1028
|
+
canBundle = bundleValue === true || bundleValue === "force" || String(bundleValue) === "true";
|
|
1029
|
+
forceDownload = bundleValue === "force";
|
|
1030
|
+
}
|
|
1015
1031
|
const rpiOption = scriptOptions?.value.properties?.find((prop) => {
|
|
1016
1032
|
return prop.type === "Property" && prop.key?.name === "proxy" && prop.value.type === "Literal";
|
|
1017
1033
|
});
|
|
@@ -1214,14 +1230,15 @@ function templatePlugin(config, registry) {
|
|
|
1214
1230
|
for (const [k, c] of Object.entries(config.registry || {})) {
|
|
1215
1231
|
if (c === false)
|
|
1216
1232
|
continue;
|
|
1217
|
-
const
|
|
1233
|
+
const entry = c;
|
|
1234
|
+
const [, scriptOptions] = entry;
|
|
1218
1235
|
if (!scriptOptions?.trigger)
|
|
1219
1236
|
continue;
|
|
1220
1237
|
const importDefinition = registry.find((i) => i.import.name.toLowerCase() === `usescript${k.toLowerCase()}`);
|
|
1221
1238
|
if (importDefinition) {
|
|
1222
1239
|
resolvedRegistryKeys.push(k);
|
|
1223
1240
|
imports.unshift(`import { ${importDefinition.import.name} } from '${importDefinition.import.from}'`);
|
|
1224
|
-
const [input] =
|
|
1241
|
+
const [input] = entry;
|
|
1225
1242
|
const opts = { ...scriptOptions };
|
|
1226
1243
|
const triggerResolved = resolveTriggerForTemplate(opts.trigger);
|
|
1227
1244
|
if (triggerResolved) {
|
|
@@ -1356,6 +1373,42 @@ function fixSelfClosingScriptComponents(nuxt) {
|
|
|
1356
1373
|
}
|
|
1357
1374
|
const UPPER_RE = /([A-Z])/g;
|
|
1358
1375
|
const toScreamingSnake = (s) => s.replace(UPPER_RE, "_$1").toUpperCase();
|
|
1376
|
+
const PROXY_SECRET_ENV_KEY = "NUXT_SCRIPTS_PROXY_SECRET";
|
|
1377
|
+
const PROXY_SECRET_ENV_LINE_RE = /^NUXT_SCRIPTS_PROXY_SECRET=/m;
|
|
1378
|
+
const PROXY_SECRET_ENV_VALUE_RE = /^NUXT_SCRIPTS_PROXY_SECRET=(.+)$/m;
|
|
1379
|
+
function resolveProxySecret(rootDir, isDev, configSecret, autoGenerate = true) {
|
|
1380
|
+
if (configSecret)
|
|
1381
|
+
return { secret: configSecret, ephemeral: false, source: "config" };
|
|
1382
|
+
const envSecret = process.env[PROXY_SECRET_ENV_KEY];
|
|
1383
|
+
if (envSecret)
|
|
1384
|
+
return { secret: envSecret, ephemeral: false, source: "env" };
|
|
1385
|
+
if (!isDev || !autoGenerate)
|
|
1386
|
+
return void 0;
|
|
1387
|
+
const secret = randomBytes(32).toString("hex");
|
|
1388
|
+
const envPath = resolve(rootDir, ".env");
|
|
1389
|
+
const line = `${PROXY_SECRET_ENV_KEY}=${secret}
|
|
1390
|
+
`;
|
|
1391
|
+
try {
|
|
1392
|
+
if (existsSync(envPath)) {
|
|
1393
|
+
const contents = readFileSync(envPath, "utf-8");
|
|
1394
|
+
if (PROXY_SECRET_ENV_LINE_RE.test(contents)) {
|
|
1395
|
+
const match = contents.match(PROXY_SECRET_ENV_VALUE_RE);
|
|
1396
|
+
if (match?.[1])
|
|
1397
|
+
return { secret: match[1].trim(), ephemeral: false, source: "dotenv-generated" };
|
|
1398
|
+
}
|
|
1399
|
+
appendFileSync(envPath, contents.endsWith("\n") ? line : `
|
|
1400
|
+
${line}`);
|
|
1401
|
+
} else {
|
|
1402
|
+
writeFileSync(envPath, `# Generated by @nuxt/scripts
|
|
1403
|
+
${line}`);
|
|
1404
|
+
}
|
|
1405
|
+
process.env[PROXY_SECRET_ENV_KEY] = secret;
|
|
1406
|
+
return { secret, ephemeral: false, source: "dotenv-generated" };
|
|
1407
|
+
} catch {
|
|
1408
|
+
process.env[PROXY_SECRET_ENV_KEY] = secret;
|
|
1409
|
+
return { secret, ephemeral: true, source: "memory-generated" };
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1359
1412
|
function isProxyDisabled(registryKey, registry2, runtimeConfig) {
|
|
1360
1413
|
const entry = registry2?.[registryKey];
|
|
1361
1414
|
if (!entry)
|
|
@@ -1451,17 +1504,23 @@ const module$1 = defineNuxtModule({
|
|
|
1451
1504
|
if (entry === false)
|
|
1452
1505
|
continue;
|
|
1453
1506
|
const input = entry[0];
|
|
1507
|
+
const scriptOptions = entry[1];
|
|
1454
1508
|
const envDefaults = scripts.find((s) => s.registryKey === key)?.envDefaults;
|
|
1509
|
+
const base = {};
|
|
1455
1510
|
if (!envDefaults || !Object.keys(envDefaults).length) {
|
|
1456
|
-
|
|
1457
|
-
|
|
1511
|
+
Object.assign(base, input);
|
|
1512
|
+
} else {
|
|
1513
|
+
const envResolved = {};
|
|
1514
|
+
for (const [field, defaultValue] of Object.entries(envDefaults)) {
|
|
1515
|
+
const envKey = `NUXT_PUBLIC_SCRIPTS_${toScreamingSnake(key)}_${toScreamingSnake(field)}`;
|
|
1516
|
+
envResolved[field] = process.env[envKey] || defaultValue;
|
|
1517
|
+
}
|
|
1518
|
+
Object.assign(base, defu(input, envResolved));
|
|
1458
1519
|
}
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
const envKey = `NUXT_PUBLIC_SCRIPTS_${toScreamingSnake(key)}_${toScreamingSnake(field)}`;
|
|
1462
|
-
envResolved[field] = process.env[envKey] || defaultValue;
|
|
1520
|
+
if (scriptOptions && Object.keys(scriptOptions).length > 0) {
|
|
1521
|
+
base.scriptOptions = scriptOptions;
|
|
1463
1522
|
}
|
|
1464
|
-
registryWithDefaults[key] =
|
|
1523
|
+
registryWithDefaults[key] = base;
|
|
1465
1524
|
}
|
|
1466
1525
|
nuxt.options.runtimeConfig.public.scripts = defu(
|
|
1467
1526
|
nuxt.options.runtimeConfig.public.scripts || {},
|
|
@@ -1491,6 +1550,8 @@ const module$1 = defineNuxtModule({
|
|
|
1491
1550
|
const composables = [
|
|
1492
1551
|
"useScript",
|
|
1493
1552
|
"useScriptEventPage",
|
|
1553
|
+
"useScriptProxyToken",
|
|
1554
|
+
"useScriptProxyUrl",
|
|
1494
1555
|
"useScriptTriggerConsent",
|
|
1495
1556
|
"useScriptTriggerElement",
|
|
1496
1557
|
"useScriptTriggerIdleTimeout",
|
|
@@ -1533,10 +1594,23 @@ const module$1 = defineNuxtModule({
|
|
|
1533
1594
|
const script = scripts.find((s) => s.registryKey === key);
|
|
1534
1595
|
if (!script?.schema)
|
|
1535
1596
|
continue;
|
|
1536
|
-
const
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1597
|
+
const isComponentOnly = !script.import;
|
|
1598
|
+
if (isComponentOnly) {
|
|
1599
|
+
if (scriptOptions && "trigger" in scriptOptions && scriptOptions.trigger !== false) {
|
|
1600
|
+
const pascal = key.charAt(0).toUpperCase() + key.slice(1);
|
|
1601
|
+
logger.warn(
|
|
1602
|
+
`[nuxt-scripts] registry.${key}: \`trigger\` has no effect on component-only scripts. Render <Script${pascal}> in your template to load the embed.`
|
|
1603
|
+
);
|
|
1604
|
+
}
|
|
1605
|
+
continue;
|
|
1606
|
+
}
|
|
1607
|
+
const willAutoLoad = scriptOptions && "trigger" in scriptOptions && scriptOptions.trigger !== false;
|
|
1608
|
+
if (willAutoLoad) {
|
|
1609
|
+
const requiredFields = extractRequiredFields(script.schema);
|
|
1610
|
+
const missing = requiredFields.filter((f) => !input[f]);
|
|
1611
|
+
if (missing.length) {
|
|
1612
|
+
logger.warn(`[nuxt-scripts] registry.${key}: missing required field${missing.length > 1 ? "s" : ""} ${missing.map((f) => `'${f}'`).join(", ")}. The script infrastructure is registered but will not function without ${missing.length > 1 ? "them" : "it"}.`);
|
|
1613
|
+
}
|
|
1540
1614
|
}
|
|
1541
1615
|
const envDefaultKeys = new Set(Object.keys(script.envDefaults || {}));
|
|
1542
1616
|
const userProvidedFields = Object.keys(input).filter((f) => !envDefaultKeys.has(f));
|
|
@@ -1649,7 +1723,7 @@ They will load directly from third-party servers.`
|
|
|
1649
1723
|
addPluginTemplate({
|
|
1650
1724
|
filename: "nuxt-scripts-intercept.client.mjs",
|
|
1651
1725
|
getContents() {
|
|
1652
|
-
return generateInterceptPluginContents(proxyPrefix);
|
|
1726
|
+
return generateInterceptPluginContents(proxyPrefix, { testMode: !!nuxt.options.test });
|
|
1653
1727
|
}
|
|
1654
1728
|
});
|
|
1655
1729
|
nuxt.options.runtimeConfig["nuxt-scripts-proxy"] = {
|
|
@@ -1661,12 +1735,12 @@ They will load directly from third-party servers.`
|
|
|
1661
1735
|
if (totalDomains > 0 && nuxt.options.dev) {
|
|
1662
1736
|
logger.success(`Proxy mode enabled for ${registryKeys.length} script(s), ${totalDomains} domain(s) proxied (privacy: ${privacyLabel})`);
|
|
1663
1737
|
}
|
|
1664
|
-
const
|
|
1665
|
-
const
|
|
1666
|
-
if (
|
|
1738
|
+
const proxyStaticPresets = ["static", "github-pages", "cloudflare-pages-static", "netlify-static", "azure-static", "firebase-static"];
|
|
1739
|
+
const proxyPreset = process.env.NITRO_PRESET || "";
|
|
1740
|
+
if (proxyStaticPresets.includes(proxyPreset)) {
|
|
1667
1741
|
logger.warn(
|
|
1668
|
-
`Proxy collection endpoints require a server runtime (detected: ${
|
|
1669
|
-
Scripts will be bundled, but collection requests will not be proxied.
|
|
1742
|
+
`Proxy collection endpoints require a server runtime (detected: ${proxyPreset || "static"}).
|
|
1743
|
+
Scripts will be bundled, but collection requests will not be proxied and URL signing will be unavailable.
|
|
1670
1744
|
Options: configure platform rewrites, switch to server-rendered mode, or disable with proxy: false.`
|
|
1671
1745
|
);
|
|
1672
1746
|
}
|
|
@@ -1713,6 +1787,7 @@ Options: configure platform rewrites, switch to server-rendered mode, or disable
|
|
|
1713
1787
|
});
|
|
1714
1788
|
const scriptsPrefix = config.prefix || "/_scripts";
|
|
1715
1789
|
const enabledEndpoints = {};
|
|
1790
|
+
let anyHandlerRequiresSigning = false;
|
|
1716
1791
|
for (const script of scripts) {
|
|
1717
1792
|
if (!script.serverHandlers?.length || !script.registryKey)
|
|
1718
1793
|
continue;
|
|
@@ -1721,11 +1796,14 @@ Options: configure platform rewrites, switch to server-rendered mode, or disable
|
|
|
1721
1796
|
continue;
|
|
1722
1797
|
enabledEndpoints[script.registryKey] = true;
|
|
1723
1798
|
for (const handler of script.serverHandlers) {
|
|
1799
|
+
const resolvedRoute = handler.route.replace("/_scripts", scriptsPrefix);
|
|
1724
1800
|
addServerHandler({
|
|
1725
|
-
route:
|
|
1801
|
+
route: resolvedRoute,
|
|
1726
1802
|
handler: handler.handler,
|
|
1727
1803
|
middleware: handler.middleware
|
|
1728
1804
|
});
|
|
1805
|
+
if (handler.requiresSigning)
|
|
1806
|
+
anyHandlerRequiresSigning = true;
|
|
1729
1807
|
}
|
|
1730
1808
|
if (script.registryKey === "gravatar") {
|
|
1731
1809
|
const gravatarConfig = config.registry?.gravatar?.[0] || {};
|
|
@@ -1745,7 +1823,45 @@ Options: configure platform rewrites, switch to server-rendered mode, or disable
|
|
|
1745
1823
|
{ endpoints: enabledEndpoints },
|
|
1746
1824
|
nuxt.options.runtimeConfig.public["nuxt-scripts"]
|
|
1747
1825
|
);
|
|
1826
|
+
const staticPresets = ["static", "github-pages", "cloudflare-pages-static", "netlify-static", "azure-static", "firebase-static"];
|
|
1827
|
+
const nitroPreset = process.env.NITRO_PRESET || "";
|
|
1828
|
+
const isStaticTarget = staticPresets.includes(nitroPreset);
|
|
1829
|
+
const isSpa = nuxt.options.ssr === false;
|
|
1830
|
+
if (anyHandlerRequiresSigning && (isSpa || isStaticTarget)) {
|
|
1831
|
+
logger.warn(
|
|
1832
|
+
`[security] URL signing requires a server runtime${isStaticTarget ? ` (detected preset: ${nitroPreset})` : " (ssr: false)"}.
|
|
1833
|
+
Proxy endpoints will work without signature verification.
|
|
1834
|
+
To enable signing, deploy with a server-rendered target or configure platform-level rewrites.`
|
|
1835
|
+
);
|
|
1836
|
+
} else if (anyHandlerRequiresSigning) {
|
|
1837
|
+
const proxySecretResolved = resolveProxySecret(
|
|
1838
|
+
nuxt.options.rootDir,
|
|
1839
|
+
!!nuxt.options.dev,
|
|
1840
|
+
config.security?.secret,
|
|
1841
|
+
config.security?.autoGenerateSecret !== false
|
|
1842
|
+
);
|
|
1843
|
+
if (proxySecretResolved?.source === "dotenv-generated")
|
|
1844
|
+
logger.info(`[security] Generated ${PROXY_SECRET_ENV_KEY} in .env for signed proxy URLs.`);
|
|
1845
|
+
else if (proxySecretResolved?.source === "memory-generated")
|
|
1846
|
+
logger.warn(`[security] Generated an in-memory ${PROXY_SECRET_ENV_KEY} (could not write .env). Signed URLs will break across restarts.`);
|
|
1847
|
+
if (proxySecretResolved?.secret) {
|
|
1848
|
+
const scriptsRuntime = nuxt.options.runtimeConfig["nuxt-scripts"];
|
|
1849
|
+
scriptsRuntime.proxySecret = proxySecretResolved.secret;
|
|
1850
|
+
if (config.security?.pageTokenMaxAge !== void 0)
|
|
1851
|
+
scriptsRuntime.pageTokenMaxAge = config.security.pageTokenMaxAge;
|
|
1852
|
+
addPlugin({
|
|
1853
|
+
src: await resolvePath("./runtime/plugins/proxy-token.server"),
|
|
1854
|
+
mode: "server"
|
|
1855
|
+
});
|
|
1856
|
+
} else if (!nuxt.options.dev) {
|
|
1857
|
+
logger.warn(
|
|
1858
|
+
`[security] ${PROXY_SECRET_ENV_KEY} is not set. Proxy endpoints will pass requests through without signature verification.
|
|
1859
|
+
Generate one with: npx @nuxt/scripts generate-secret
|
|
1860
|
+
Then set the env var: ${PROXY_SECRET_ENV_KEY}=<secret>`
|
|
1861
|
+
);
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1748
1864
|
}
|
|
1749
1865
|
});
|
|
1750
1866
|
|
|
1751
|
-
export { applyAutoInject, module$1 as default, isProxyDisabled };
|
|
1867
|
+
export { applyAutoInject, module$1 as default, isProxyDisabled, resolveProxySecret };
|
package/dist/registry.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ProxyPrivacyInput } from '../dist/runtime/server/utils/privacy.js';
|
|
2
2
|
import { ScriptCapabilities, RegistryScript, RegistryScriptKey, ProxyConfig, ProxyCapability, ProxyAutoInject, ResolvedProxyAutoInject } from '../dist/runtime/types.js';
|
|
3
|
+
export { ScriptCapabilities } from '../dist/runtime/types.js';
|
|
3
4
|
|
|
4
5
|
interface RegistryScriptMeta {
|
|
5
6
|
/** Registry key (e.g. 'plausibleAnalytics') */
|
package/dist/registry.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ProxyPrivacyInput } from '../dist/runtime/server/utils/privacy.js';
|
|
2
2
|
import { ScriptCapabilities, RegistryScript, RegistryScriptKey, ProxyConfig, ProxyCapability, ProxyAutoInject, ResolvedProxyAutoInject } from '../dist/runtime/types.js';
|
|
3
|
+
export { ScriptCapabilities } from '../dist/runtime/types.js';
|
|
3
4
|
|
|
4
5
|
interface RegistryScriptMeta {
|
|
5
6
|
/** Registry key (e.g. 'plausibleAnalytics') */
|
package/dist/registry.mjs
CHANGED
|
@@ -126,7 +126,7 @@ const registryMeta = [
|
|
|
126
126
|
m("intercom", "Intercom", "support", "useScriptIntercom", { bundle: true, proxy: true }, PRIVACY_IP_ONLY),
|
|
127
127
|
m("crisp", "Crisp", "support", "useScriptCrisp", { bundle: true }, null),
|
|
128
128
|
// cdn
|
|
129
|
-
m("npm", "NPM", "cdn", "useScriptNpm", {}, null),
|
|
129
|
+
m("npm", "NPM", "cdn", "useScriptNpm", { bundle: true }, null),
|
|
130
130
|
// utility
|
|
131
131
|
m("googleRecaptcha", "Google reCAPTCHA", "utility", "useScriptGoogleRecaptcha", {}, null),
|
|
132
132
|
m("googleSignIn", "Google Sign-In", "utility", "useScriptGoogleSignIn", {}, null),
|
|
@@ -346,7 +346,7 @@ async function registry(resolve) {
|
|
|
346
346
|
return "https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";
|
|
347
347
|
}
|
|
348
348
|
},
|
|
349
|
-
partytown: { forwards: ["mixpanel", "mixpanel.init", "mixpanel.track", "mixpanel.identify", "mixpanel.people.set", "mixpanel.reset", "mixpanel.register"] }
|
|
349
|
+
partytown: { forwards: ["mixpanel", "mixpanel.init", "mixpanel.track", "mixpanel.identify", "mixpanel.people.set", "mixpanel.reset", "mixpanel.register", "mixpanel.opt_in_tracking", "mixpanel.opt_out_tracking"] }
|
|
350
350
|
}),
|
|
351
351
|
// ad
|
|
352
352
|
def("bingUet", {
|
|
@@ -401,7 +401,7 @@ async function registry(resolve) {
|
|
|
401
401
|
domains: ["analytics.tiktok.com", "mon.tiktok.com", "mcs.tiktok.com"],
|
|
402
402
|
privacy: PRIVACY_FULL
|
|
403
403
|
},
|
|
404
|
-
partytown: { forwards: ["ttq.track", "ttq.page", "ttq.identify"] }
|
|
404
|
+
partytown: { forwards: ["ttq.track", "ttq.page", "ttq.identify", "ttq.grantConsent", "ttq.revokeConsent", "ttq.holdConsent"] }
|
|
405
405
|
}),
|
|
406
406
|
def("snapchatPixel", {
|
|
407
407
|
schema: SnapTrPixelOptions,
|
|
@@ -503,7 +503,7 @@ async function registry(resolve) {
|
|
|
503
503
|
domains: ["www.clarity.ms", "scripts.clarity.ms", "d.clarity.ms", "e.clarity.ms", "k.clarity.ms", "c.clarity.ms", "a.clarity.ms", "b.clarity.ms"],
|
|
504
504
|
privacy: PRIVACY_HEATMAP
|
|
505
505
|
},
|
|
506
|
-
partytown: { forwards: [] }
|
|
506
|
+
partytown: { forwards: ["clarity"] }
|
|
507
507
|
}),
|
|
508
508
|
// payments
|
|
509
509
|
def("stripe", {
|
|
@@ -554,8 +554,8 @@ async function registry(resolve) {
|
|
|
554
554
|
envDefaults: { apiKey: "" },
|
|
555
555
|
category: "content",
|
|
556
556
|
serverHandlers: [
|
|
557
|
-
{ route: "/_scripts/proxy/google-static-maps", handler: "./runtime/server/google-static-maps-proxy" },
|
|
558
|
-
{ route: "/_scripts/proxy/google-maps-geocode", handler: "./runtime/server/google-maps-geocode-proxy" }
|
|
557
|
+
{ route: "/_scripts/proxy/google-static-maps", handler: "./runtime/server/google-static-maps-proxy", requiresSigning: true },
|
|
558
|
+
{ route: "/_scripts/proxy/google-maps-geocode", handler: "./runtime/server/google-maps-geocode-proxy", requiresSigning: true }
|
|
559
559
|
]
|
|
560
560
|
}),
|
|
561
561
|
def("blueskyEmbed", {
|
|
@@ -564,8 +564,8 @@ async function registry(resolve) {
|
|
|
564
564
|
label: "Bluesky Embed",
|
|
565
565
|
category: "content",
|
|
566
566
|
serverHandlers: [
|
|
567
|
-
{ route: "/_scripts/embed/bluesky", handler: "./runtime/server/bluesky-embed" },
|
|
568
|
-
{ route: "/_scripts/embed/bluesky-image", handler: "./runtime/server/bluesky-embed-image" }
|
|
567
|
+
{ route: "/_scripts/embed/bluesky", handler: "./runtime/server/bluesky-embed", requiresSigning: true },
|
|
568
|
+
{ route: "/_scripts/embed/bluesky-image", handler: "./runtime/server/bluesky-embed-image", requiresSigning: true }
|
|
569
569
|
]
|
|
570
570
|
}),
|
|
571
571
|
def("instagramEmbed", {
|
|
@@ -574,9 +574,9 @@ async function registry(resolve) {
|
|
|
574
574
|
label: "Instagram Embed",
|
|
575
575
|
category: "content",
|
|
576
576
|
serverHandlers: [
|
|
577
|
-
{ route: "/_scripts/embed/instagram", handler: "./runtime/server/instagram-embed" },
|
|
578
|
-
{ route: "/_scripts/embed/instagram-image", handler: "./runtime/server/instagram-embed-image" },
|
|
579
|
-
{ route: "/_scripts/embed/instagram-asset", handler: "./runtime/server/instagram-embed-asset" }
|
|
577
|
+
{ route: "/_scripts/embed/instagram", handler: "./runtime/server/instagram-embed", requiresSigning: true },
|
|
578
|
+
{ route: "/_scripts/embed/instagram-image", handler: "./runtime/server/instagram-embed-image", requiresSigning: true },
|
|
579
|
+
{ route: "/_scripts/embed/instagram-asset", handler: "./runtime/server/instagram-embed-asset", requiresSigning: true }
|
|
580
580
|
]
|
|
581
581
|
}),
|
|
582
582
|
def("xEmbed", {
|
|
@@ -585,8 +585,8 @@ async function registry(resolve) {
|
|
|
585
585
|
label: "X Embed",
|
|
586
586
|
category: "content",
|
|
587
587
|
serverHandlers: [
|
|
588
|
-
{ route: "/_scripts/embed/x", handler: "./runtime/server/x-embed" },
|
|
589
|
-
{ route: "/_scripts/embed/x-image", handler: "./runtime/server/x-embed-image" }
|
|
588
|
+
{ route: "/_scripts/embed/x", handler: "./runtime/server/x-embed", requiresSigning: true },
|
|
589
|
+
{ route: "/_scripts/embed/x-image", handler: "./runtime/server/x-embed-image", requiresSigning: true }
|
|
590
590
|
]
|
|
591
591
|
}),
|
|
592
592
|
// support
|
|
@@ -690,7 +690,7 @@ async function registry(resolve) {
|
|
|
690
690
|
privacy: PRIVACY_IP_ONLY
|
|
691
691
|
},
|
|
692
692
|
serverHandlers: [
|
|
693
|
-
{ route: "/_scripts/proxy/gravatar", handler: "./runtime/server/gravatar-proxy" }
|
|
693
|
+
{ route: "/_scripts/proxy/gravatar", handler: "./runtime/server/gravatar-proxy", requiresSigning: true }
|
|
694
694
|
]
|
|
695
695
|
})
|
|
696
696
|
]);
|