@nuxt/scripts 1.0.0-beta.3 → 1.0.0-beta.31
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/README.md +3 -3
- package/dist/client/200.html +1 -1
- package/dist/client/404.html +1 -1
- package/dist/client/_nuxt/{DdVDSbUA.js → 6CwTUC2b.js} +1 -1
- package/dist/client/_nuxt/{CD5B-xvT.js → B71AlSZ1.js} +1 -1
- package/dist/client/_nuxt/{Ds2G8aQM.js → BYGJV5dd.js} +1 -1
- package/dist/client/_nuxt/V4W-T8W6.js +162 -0
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/70b59a3e-a025-4a77-a25a-dfadf5b1749d.json +1 -0
- package/dist/client/_nuxt/entry.C5SUNdim.css +1 -0
- package/dist/client/_nuxt/error-404.1K8v8Su2.css +1 -0
- package/dist/client/_nuxt/error-500.B9qvKpQm.css +1 -0
- package/dist/client/index.html +1 -1
- package/dist/module.d.mts +6 -18
- package/dist/module.d.ts +164 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +908 -645
- package/dist/registry.d.ts +6 -0
- package/dist/registry.mjs +244 -78
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.d.vue.ts +16 -9
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue +57 -30
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue.d.ts +16 -9
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.d.vue.ts +22 -39
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.vue +69 -72
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.vue.d.ts +22 -39
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsCircle.d.vue.ts +5 -1
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsCircle.vue +25 -38
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsCircle.vue.d.ts +5 -1
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsGeoJson.d.vue.ts +43 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsGeoJson.vue +61 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsGeoJson.vue.d.ts +43 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsHeatmapLayer.d.vue.ts +4 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsHeatmapLayer.vue +22 -26
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsHeatmapLayer.vue.d.ts +4 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.d.vue.ts +9 -5
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.vue +62 -53
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.vue.d.ts +9 -5
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.d.vue.ts +26 -11
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue +48 -45
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue.d.ts +26 -11
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.d.vue.ts +15 -4
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue +47 -37
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue.d.ts +15 -4
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.d.vue.ts +77 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.vue +209 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.vue.d.ts +77 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.d.vue.ts +4 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.vue +23 -32
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.vue.d.ts +4 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolygon.d.vue.ts +7 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolygon.vue +24 -38
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolygon.vue.d.ts +7 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolyline.d.vue.ts +7 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolyline.vue +24 -38
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolyline.vue.d.ts +7 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsRectangle.d.vue.ts +7 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsRectangle.vue +25 -38
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsRectangle.vue.d.ts +7 -3
- package/dist/runtime/components/GoogleMaps/bindGoogleMapsEvents.d.ts +13 -0
- package/dist/runtime/components/GoogleMaps/bindGoogleMapsEvents.js +8 -0
- package/dist/runtime/components/GoogleMaps/injectionKeys.d.ts +13 -0
- package/dist/runtime/components/GoogleMaps/injectionKeys.js +3 -0
- package/dist/runtime/components/GoogleMaps/useGoogleMapsResource.d.ts +26 -0
- package/dist/runtime/components/GoogleMaps/useGoogleMapsResource.js +42 -0
- package/dist/runtime/components/ScriptBlueskyEmbed.d.vue.ts +87 -0
- package/dist/runtime/components/ScriptBlueskyEmbed.vue +85 -0
- package/dist/runtime/components/ScriptBlueskyEmbed.vue.d.ts +87 -0
- package/dist/runtime/components/ScriptCrisp.vue +1 -1
- package/dist/runtime/components/ScriptGoogleAdsense.vue +1 -1
- package/dist/runtime/components/ScriptGravatar.d.vue.ts +22 -0
- package/dist/runtime/components/ScriptGravatar.vue +46 -0
- package/dist/runtime/components/ScriptGravatar.vue.d.ts +22 -0
- package/dist/runtime/components/ScriptInstagramEmbed.d.vue.ts +2 -2
- package/dist/runtime/components/ScriptInstagramEmbed.vue +5 -2
- package/dist/runtime/components/ScriptInstagramEmbed.vue.d.ts +2 -2
- package/dist/runtime/components/ScriptIntercom.vue +4 -3
- package/dist/runtime/components/ScriptPayPalButtons.d.vue.ts +43 -32
- package/dist/runtime/components/ScriptPayPalButtons.vue +48 -79
- package/dist/runtime/components/ScriptPayPalButtons.vue.d.ts +43 -32
- package/dist/runtime/components/ScriptPayPalMessages.d.vue.ts +37 -23
- package/dist/runtime/components/ScriptPayPalMessages.vue +46 -50
- package/dist/runtime/components/ScriptPayPalMessages.vue.d.ts +37 -23
- package/dist/runtime/components/ScriptStripePricingTable.vue +2 -2
- package/dist/runtime/components/ScriptVimeoPlayer.d.vue.ts +9 -0
- package/dist/runtime/components/ScriptVimeoPlayer.vue +13 -10
- package/dist/runtime/components/ScriptVimeoPlayer.vue.d.ts +9 -0
- package/dist/runtime/components/ScriptXEmbed.d.vue.ts +2 -2
- package/dist/runtime/components/ScriptXEmbed.vue +6 -3
- package/dist/runtime/components/ScriptXEmbed.vue.d.ts +2 -2
- package/dist/runtime/components/ScriptYouTubePlayer.d.vue.ts +2 -2
- package/dist/runtime/components/ScriptYouTubePlayer.vue +11 -5
- package/dist/runtime/components/ScriptYouTubePlayer.vue.d.ts +2 -2
- package/dist/runtime/composables/useScript.js +13 -6
- package/dist/runtime/composables/useScriptEventPage.js +2 -2
- package/dist/runtime/composables/useScriptTriggerConsent.d.ts +10 -0
- package/dist/runtime/composables/useScriptTriggerConsent.js +33 -20
- package/dist/runtime/composables/useScriptTriggerElement.js +1 -1
- package/dist/runtime/composables/useScriptTriggerIdleTimeout.js +1 -1
- package/dist/runtime/registry/bing-uet.d.ts +20 -0
- package/dist/runtime/registry/bing-uet.js +29 -0
- package/dist/runtime/registry/bluesky-embed.d.ts +116 -0
- package/dist/runtime/registry/bluesky-embed.js +72 -0
- package/dist/runtime/registry/clarity.d.ts +10 -15
- package/dist/runtime/registry/clarity.js +22 -31
- package/dist/runtime/registry/cloudflare-web-analytics.d.ts +2 -13
- package/dist/runtime/registry/cloudflare-web-analytics.js +2 -14
- package/dist/runtime/registry/crisp.d.ts +10 -40
- package/dist/runtime/registry/crisp.js +2 -33
- package/dist/runtime/registry/databuddy-analytics.d.ts +2 -35
- package/dist/runtime/registry/databuddy-analytics.js +20 -45
- package/dist/runtime/registry/fathom-analytics.d.ts +7 -26
- package/dist/runtime/registry/fathom-analytics.js +2 -24
- package/dist/runtime/registry/google-adsense.d.ts +3 -11
- package/dist/runtime/registry/google-adsense.js +2 -11
- package/dist/runtime/registry/google-analytics.d.ts +3 -5
- package/dist/runtime/registry/google-analytics.js +3 -8
- package/dist/runtime/registry/google-maps.d.ts +3 -9
- package/dist/runtime/registry/google-maps.js +2 -8
- package/dist/runtime/registry/google-recaptcha.d.ts +2 -6
- package/dist/runtime/registry/google-recaptcha.js +4 -12
- package/dist/runtime/registry/google-sign-in.d.ts +2 -13
- package/dist/runtime/registry/google-sign-in.js +2 -22
- package/dist/runtime/registry/google-tag-manager.d.ts +3 -28
- package/dist/runtime/registry/google-tag-manager.js +4 -27
- package/dist/runtime/registry/gravatar.d.ts +26 -0
- package/dist/runtime/registry/gravatar.js +33 -0
- package/dist/runtime/registry/hotjar.d.ts +4 -6
- package/dist/runtime/registry/hotjar.js +2 -5
- package/dist/runtime/registry/instagram-embed.d.ts +3 -18
- package/dist/runtime/registry/instagram-embed.js +4 -19
- package/dist/runtime/registry/intercom.d.ts +4 -12
- package/dist/runtime/registry/intercom.js +2 -12
- package/dist/runtime/registry/matomo-analytics.d.ts +3 -12
- package/dist/runtime/registry/matomo-analytics.js +3 -12
- package/dist/runtime/registry/meta-pixel.d.ts +4 -6
- package/dist/runtime/registry/meta-pixel.js +2 -4
- package/dist/runtime/registry/mixpanel-analytics.d.ts +22 -0
- package/dist/runtime/registry/mixpanel-analytics.js +46 -0
- package/dist/runtime/registry/npm.d.ts +3 -7
- package/dist/runtime/registry/npm.js +2 -9
- package/dist/runtime/registry/paypal.d.ts +4 -25
- package/dist/runtime/registry/paypal.js +3 -66
- package/dist/runtime/registry/plausible-analytics.js +18 -13
- package/dist/runtime/registry/posthog.d.ts +10 -12
- package/dist/runtime/registry/posthog.js +7 -14
- package/dist/runtime/registry/reddit-pixel.d.ts +5 -6
- package/dist/runtime/registry/reddit-pixel.js +2 -4
- package/dist/runtime/registry/rybbit-analytics.d.ts +2 -14
- package/dist/runtime/registry/rybbit-analytics.js +10 -20
- package/dist/runtime/registry/schemas.d.ts +982 -0
- package/dist/runtime/registry/schemas.js +937 -0
- package/dist/runtime/registry/segment.d.ts +2 -5
- package/dist/runtime/registry/segment.js +2 -5
- package/dist/runtime/registry/snapchat-pixel.d.ts +4 -33
- package/dist/runtime/registry/snapchat-pixel.js +2 -20
- package/dist/runtime/registry/stripe.d.ts +3 -4
- package/dist/runtime/registry/stripe.js +2 -4
- package/dist/runtime/registry/tiktok-pixel.d.ts +4 -7
- package/dist/runtime/registry/tiktok-pixel.js +2 -6
- package/dist/runtime/registry/umami-analytics.d.ts +2 -31
- package/dist/runtime/registry/umami-analytics.js +2 -36
- package/dist/runtime/registry/vercel-analytics.d.ts +29 -0
- package/dist/runtime/registry/vercel-analytics.js +84 -0
- package/dist/runtime/registry/vimeo-player.d.ts +2 -2
- package/dist/runtime/registry/vimeo-player.js +1 -1
- package/dist/runtime/registry/x-embed.d.ts +3 -17
- package/dist/runtime/registry/x-embed.js +3 -18
- package/dist/runtime/registry/x-pixel.d.ts +4 -7
- package/dist/runtime/registry/x-pixel.js +2 -5
- package/dist/runtime/registry/youtube-player.d.ts +7 -7
- package/dist/runtime/registry/youtube-player.js +1 -1
- package/dist/runtime/server/{sw-handler.d.ts → bluesky-embed-image.d.ts} +1 -1
- package/dist/runtime/server/bluesky-embed-image.js +7 -0
- package/dist/runtime/server/bluesky-embed.d.ts +16 -0
- package/dist/runtime/server/bluesky-embed.js +59 -0
- package/dist/runtime/server/google-maps-geocode-proxy.d.ts +2 -0
- package/dist/runtime/server/google-maps-geocode-proxy.js +34 -0
- package/dist/runtime/server/google-static-maps-proxy.js +2 -13
- package/dist/runtime/server/gravatar-proxy.d.ts +2 -0
- package/dist/runtime/server/gravatar-proxy.js +46 -0
- package/dist/runtime/server/instagram-embed-asset.js +8 -41
- package/dist/runtime/server/instagram-embed-image.js +6 -53
- package/dist/runtime/server/instagram-embed.d.ts +16 -0
- package/dist/runtime/server/instagram-embed.js +173 -35
- package/dist/runtime/server/proxy-handler.js +144 -113
- package/dist/runtime/server/utils/image-proxy.d.ts +12 -0
- package/dist/runtime/server/utils/image-proxy.js +70 -0
- package/dist/runtime/server/utils/privacy.d.ts +1 -2
- package/dist/runtime/server/utils/privacy.js +54 -34
- package/dist/runtime/server/x-embed-image.js +5 -49
- package/dist/runtime/server/x-embed.js +3 -2
- package/dist/runtime/types.d.ts +74 -40
- package/dist/runtime/utils/pure.d.ts +1 -5
- package/dist/runtime/utils/pure.js +0 -67
- package/dist/runtime/utils.d.ts +4 -3
- package/dist/runtime/utils.js +24 -10
- package/dist/shared/scripts.D7e2ENu6.mjs +211 -0
- package/dist/stats.d.mts +202 -0
- package/dist/stats.d.ts +202 -0
- package/dist/stats.mjs +3860 -0
- package/dist/types-source.d.mts +17 -0
- package/dist/types-source.d.ts +17 -0
- package/dist/types-source.mjs +3614 -0
- package/package.json +52 -38
- package/dist/client/_nuxt/D-kOnTuH.js +0 -162
- package/dist/client/_nuxt/builds/meta/f1474569-6922-450d-bc3f-4fd5f3e1391a.json +0 -1
- package/dist/client/_nuxt/entry.D45OuV0w.css +0 -1
- package/dist/client/_nuxt/error-404.B57D-jUQ.css +0 -1
- package/dist/client/_nuxt/error-500.DTHUW7BI.css +0 -1
- package/dist/runtime/components/ScriptPayPalMarks.d.vue.ts +0 -52
- package/dist/runtime/components/ScriptPayPalMarks.vue +0 -69
- package/dist/runtime/components/ScriptPayPalMarks.vue.d.ts +0 -52
- package/dist/runtime/plugins/sw-register.client.d.ts +0 -2
- package/dist/runtime/plugins/sw-register.client.js +0 -12
- package/dist/runtime/server/sw-handler.js +0 -25
- package/dist/runtime/sw/proxy-sw.template.d.ts +0 -1
- package/dist/runtime/sw/proxy-sw.template.js +0 -54
package/dist/module.mjs
CHANGED
|
@@ -1,89 +1,285 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { useLogger, addServerHandler, addPluginTemplate, useNuxt, addDevServerHandler, extendRouteRules, tryUseNuxt, extendViteConfig, logger as logger$1, addTypeTemplate, defineNuxtModule, createResolver, hasNuxtModule, addImports, addComponentsDir, addTemplate, addBuildPlugin } from '@nuxt/kit';
|
|
3
3
|
import { defu } from 'defu';
|
|
4
|
+
import { join, resolve, relative } from 'pathe';
|
|
4
5
|
import { resolvePackageJSON, readPackageJSON } from 'pkg-types';
|
|
6
|
+
import { lazyEventHandler, eventHandler, createError } from 'h3';
|
|
7
|
+
import { fetch, $fetch } from 'ofetch';
|
|
8
|
+
import { joinURL, parseURL, parseQuery, hasProtocol } from 'ufo';
|
|
9
|
+
import { createStorage } from 'unstorage';
|
|
10
|
+
import fsDriver from 'unstorage/drivers/fs-lite';
|
|
5
11
|
import { addCustomTab } from '@nuxt/devtools-kit';
|
|
12
|
+
import { isCI, provider } from 'std-env';
|
|
13
|
+
import { parseAndWalk, ScopeTracker, walk, ScopeTrackerFunction, ScopeTrackerIdentifier, ScopeTrackerFunctionParam, ScopeTrackerVariable } from 'oxc-walker';
|
|
14
|
+
import { createUnplugin } from 'unplugin';
|
|
15
|
+
import { pathToFileURL } from 'node:url';
|
|
6
16
|
import { createHash } from 'node:crypto';
|
|
7
17
|
import fsp from 'node:fs/promises';
|
|
8
|
-
import {
|
|
18
|
+
import { colors } from 'consola/utils';
|
|
9
19
|
import MagicString from 'magic-string';
|
|
10
|
-
import { parseAndWalk } from 'oxc-walker';
|
|
11
|
-
import { joinURL, parseURL, parseQuery, hasProtocol } from 'ufo';
|
|
12
20
|
import { hash } from 'ohash';
|
|
13
|
-
import { join, resolve, relative } from 'pathe';
|
|
14
|
-
import { colors } from 'consola/utils';
|
|
15
|
-
import { fetch, $fetch } from 'ofetch';
|
|
16
|
-
import { lazyEventHandler, eventHandler, createError } from 'h3';
|
|
17
|
-
import { createStorage } from 'unstorage';
|
|
18
|
-
import fsDriver from 'unstorage/drivers/fs-lite';
|
|
19
|
-
import { rewriteScriptUrls } from '../dist/runtime/utils/pure.js';
|
|
20
|
-
import { pathToFileURL } from 'node:url';
|
|
21
|
-
import { isCI, provider } from 'std-env';
|
|
22
21
|
import { registry } from './registry.mjs';
|
|
22
|
+
import { g as getAllProxyConfigs } from './shared/scripts.D7e2ENu6.mjs';
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
function generatePartytownResolveUrl(proxyPrefix) {
|
|
25
|
+
return `function(url, location, type) {
|
|
26
|
+
if (url.origin !== location.origin) {
|
|
27
|
+
return new URL(${JSON.stringify(proxyPrefix)} + '/' + url.host + url.pathname + url.search, location.origin);
|
|
28
|
+
}
|
|
29
|
+
}`;
|
|
30
|
+
}
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
)
|
|
32
|
+
const logger = useLogger("@nuxt/scripts");
|
|
33
|
+
|
|
34
|
+
function generateInterceptPluginContents(proxyPrefix) {
|
|
35
|
+
return `export default defineNuxtPlugin({
|
|
36
|
+
name: 'nuxt-scripts:intercept',
|
|
37
|
+
enforce: 'pre',
|
|
38
|
+
setup() {
|
|
39
|
+
const proxyPrefix = ${JSON.stringify(proxyPrefix)};
|
|
40
|
+
const origBeacon = typeof navigator !== 'undefined' && navigator.sendBeacon
|
|
41
|
+
? navigator.sendBeacon.bind(navigator)
|
|
42
|
+
: () => false;
|
|
43
|
+
const origFetch = globalThis.fetch.bind(globalThis);
|
|
44
|
+
|
|
45
|
+
function proxyUrl(url) {
|
|
46
|
+
try {
|
|
47
|
+
const parsed = new URL(url, location.origin);
|
|
48
|
+
if (parsed.origin !== location.origin)
|
|
49
|
+
return location.origin + proxyPrefix + '/' + parsed.host + parsed.pathname + parsed.search;
|
|
50
|
+
} catch {}
|
|
51
|
+
return url;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// XMLHttpRequest wrapper \u2014 intercepts .open() to rewrite URL
|
|
55
|
+
const OrigXHR = XMLHttpRequest;
|
|
56
|
+
class ProxiedXHR extends OrigXHR {
|
|
57
|
+
open() {
|
|
58
|
+
const args = Array.from(arguments);
|
|
59
|
+
if (typeof args[1] === 'string') args[1] = proxyUrl(args[1]);
|
|
60
|
+
return super.open.apply(this, args);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Image wrapper \u2014 intercepts .src setter to rewrite URL
|
|
64
|
+
const OrigImage = Image;
|
|
65
|
+
const origSrcDesc = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype, 'src');
|
|
66
|
+
function ProxiedImage(w, h) {
|
|
67
|
+
const img = arguments.length === 2 ? new OrigImage(w, h)
|
|
68
|
+
: arguments.length === 1 ? new OrigImage(w) : new OrigImage();
|
|
69
|
+
if (origSrcDesc && origSrcDesc.set) {
|
|
70
|
+
Object.defineProperty(img, 'src', {
|
|
71
|
+
get() { return origSrcDesc.get.call(this); },
|
|
72
|
+
set(v) { origSrcDesc.set.call(this, typeof v === 'string' ? proxyUrl(v) : v); },
|
|
73
|
+
configurable: true,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return img;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
globalThis.__nuxtScripts = {
|
|
80
|
+
sendBeacon: (url, data) => origBeacon(proxyUrl(url), data),
|
|
81
|
+
fetch: (url, opts) => origFetch(typeof url === 'string' ? proxyUrl(url) : url, opts),
|
|
82
|
+
XMLHttpRequest: ProxiedXHR,
|
|
83
|
+
Image: ProxiedImage,
|
|
84
|
+
};
|
|
85
|
+
},
|
|
86
|
+
})
|
|
87
|
+
`;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function setupFirstParty(config, resolvePath) {
|
|
91
|
+
const enabled = !!config.firstParty;
|
|
92
|
+
const proxyPrefix = typeof config.firstParty === "object" ? config.firstParty.proxyPrefix || "/_scripts/p" : "/_scripts/p";
|
|
93
|
+
const privacy = typeof config.firstParty === "object" ? config.firstParty.privacy : void 0;
|
|
94
|
+
const assetsPrefix = config.assets?.prefix || "/_scripts/assets";
|
|
95
|
+
const proxyConfigs = enabled ? getAllProxyConfigs() : {};
|
|
96
|
+
const firstParty = { enabled, proxyPrefix, privacy, assetsPrefix, proxyConfigs };
|
|
97
|
+
if (enabled) {
|
|
98
|
+
const proxyHandlerPath = await resolvePath("./runtime/server/proxy-handler");
|
|
99
|
+
logger.debug("[nuxt-scripts] Registering proxy handler:", `${proxyPrefix}/**`, "->", proxyHandlerPath);
|
|
100
|
+
addServerHandler({
|
|
101
|
+
route: `${proxyPrefix}/**`,
|
|
102
|
+
handler: proxyHandlerPath
|
|
37
103
|
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
104
|
+
}
|
|
105
|
+
return firstParty;
|
|
106
|
+
}
|
|
107
|
+
function applyAutoInject(registry, runtimeConfig, proxyPrefix, registryKey, autoInject) {
|
|
108
|
+
const entry = registry[registryKey];
|
|
109
|
+
if (!entry)
|
|
110
|
+
return;
|
|
111
|
+
const input = entry[0];
|
|
112
|
+
const scriptOptions = entry[1];
|
|
113
|
+
if (input?.firstParty === false || scriptOptions?.firstParty === false)
|
|
114
|
+
return;
|
|
115
|
+
const rtScripts = runtimeConfig.public?.scripts;
|
|
116
|
+
const rtEntry = rtScripts?.[registryKey];
|
|
117
|
+
const config = rtEntry && typeof rtEntry === "object" ? rtEntry : input;
|
|
118
|
+
if (!config || config[autoInject.configField])
|
|
119
|
+
return;
|
|
120
|
+
const value = autoInject.computeValue(proxyPrefix, config);
|
|
121
|
+
input[autoInject.configField] = value;
|
|
122
|
+
if (rtEntry && typeof rtEntry === "object" && rtEntry !== input)
|
|
123
|
+
rtEntry[autoInject.configField] = value;
|
|
124
|
+
}
|
|
125
|
+
function computePrivacyLevel(privacy) {
|
|
126
|
+
const flags = Object.values(privacy);
|
|
127
|
+
if (flags.every(Boolean))
|
|
128
|
+
return "full";
|
|
129
|
+
if (flags.some(Boolean))
|
|
130
|
+
return "partial";
|
|
131
|
+
return "none";
|
|
132
|
+
}
|
|
133
|
+
function finalizeFirstParty(opts) {
|
|
134
|
+
const { firstParty, registryScripts, nuxtOptions } = opts;
|
|
135
|
+
const { proxyConfigs, proxyPrefix } = firstParty;
|
|
136
|
+
const registryKeys = Object.keys(opts.registry || {});
|
|
137
|
+
const scriptByKey = /* @__PURE__ */ new Map();
|
|
138
|
+
for (const script of registryScripts) {
|
|
139
|
+
if (script.registryKey)
|
|
140
|
+
scriptByKey.set(script.registryKey, script);
|
|
141
|
+
}
|
|
142
|
+
const domainPrivacy = {};
|
|
143
|
+
const unsupportedScripts = [];
|
|
144
|
+
const unmatchedScripts = [];
|
|
145
|
+
let totalDomains = 0;
|
|
146
|
+
const devtoolsScripts = [];
|
|
147
|
+
for (const key of registryKeys) {
|
|
148
|
+
const script = scriptByKey.get(key);
|
|
149
|
+
if (!script) {
|
|
150
|
+
unmatchedScripts.push(key);
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (script.proxy === false)
|
|
154
|
+
continue;
|
|
155
|
+
const registryEntry = opts.registry?.[key];
|
|
156
|
+
const entryScriptOptions = registryEntry?.[1];
|
|
157
|
+
const entryInput = registryEntry?.[0];
|
|
158
|
+
if (entryScriptOptions?.firstParty === false || entryInput?.firstParty === false)
|
|
159
|
+
continue;
|
|
160
|
+
const configKey = script.proxy || key;
|
|
161
|
+
const proxyConfig = proxyConfigs[configKey];
|
|
162
|
+
if (!proxyConfig) {
|
|
163
|
+
if (script.scriptBundling !== false)
|
|
164
|
+
unsupportedScripts.push(key);
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
for (const domain of proxyConfig.domains) {
|
|
168
|
+
domainPrivacy[domain] = proxyConfig.privacy;
|
|
169
|
+
totalDomains++;
|
|
170
|
+
}
|
|
171
|
+
if (proxyConfig.autoInject && opts.registry)
|
|
172
|
+
applyAutoInject(opts.registry, nuxtOptions.runtimeConfig, proxyPrefix, key, proxyConfig.autoInject);
|
|
173
|
+
if (nuxtOptions.dev) {
|
|
174
|
+
const privacy = proxyConfig.privacy;
|
|
175
|
+
const normalizedPrivacy = {
|
|
176
|
+
ip: !!privacy.ip,
|
|
177
|
+
userAgent: !!privacy.userAgent,
|
|
178
|
+
language: !!privacy.language,
|
|
179
|
+
screen: !!privacy.screen,
|
|
180
|
+
timezone: !!privacy.timezone,
|
|
181
|
+
hardware: !!privacy.hardware
|
|
47
182
|
};
|
|
48
|
-
|
|
183
|
+
const logo = script.logo;
|
|
184
|
+
const logoStr = typeof logo === "object" ? logo.dark || logo.light : logo || "";
|
|
185
|
+
devtoolsScripts.push({
|
|
186
|
+
registryKey: key,
|
|
187
|
+
label: script.label || key,
|
|
188
|
+
logo: logoStr,
|
|
189
|
+
category: script.category || "unknown",
|
|
190
|
+
configKey,
|
|
191
|
+
mechanism: script.src === false ? "config-injection-proxy" : "bundle-rewrite-intercept",
|
|
192
|
+
hasAutoInject: !!proxyConfig.autoInject,
|
|
193
|
+
autoInjectField: proxyConfig.autoInject?.configField,
|
|
194
|
+
hasPostProcess: !!proxyConfig.postProcess,
|
|
195
|
+
privacy: normalizedPrivacy,
|
|
196
|
+
privacyLevel: computePrivacyLevel(normalizedPrivacy),
|
|
197
|
+
domains: [...proxyConfig.domains]
|
|
198
|
+
});
|
|
199
|
+
}
|
|
49
200
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
201
|
+
if (unmatchedScripts.length) {
|
|
202
|
+
logger.warn(
|
|
203
|
+
`First-party mode: could not find registry scripts for: ${unmatchedScripts.join(", ")}.
|
|
204
|
+
These scripts will not have proxy routes registered. Check that the registry key matches a known script.`
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
if (unsupportedScripts.length && nuxtOptions.dev) {
|
|
208
|
+
logger.warn(
|
|
209
|
+
`First-party mode is enabled but these scripts don't support it yet: ${unsupportedScripts.join(", ")}.
|
|
210
|
+
They will load directly from third-party servers. Request support at https://github.com/nuxt/scripts/issues`
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
addPluginTemplate({
|
|
214
|
+
filename: "nuxt-scripts-intercept.client.mjs",
|
|
215
|
+
getContents() {
|
|
216
|
+
return generateInterceptPluginContents(proxyPrefix);
|
|
61
217
|
}
|
|
62
218
|
});
|
|
63
|
-
|
|
219
|
+
nuxtOptions.runtimeConfig["nuxt-scripts-proxy"] = {
|
|
220
|
+
proxyPrefix,
|
|
221
|
+
domainPrivacy,
|
|
222
|
+
privacy: firstParty.privacy
|
|
223
|
+
};
|
|
224
|
+
const privacyLabel = firstParty.privacy === void 0 ? "per-script" : typeof firstParty.privacy === "boolean" ? firstParty.privacy ? "anonymize" : "passthrough" : "custom";
|
|
225
|
+
if (totalDomains > 0 && nuxtOptions.dev) {
|
|
226
|
+
const scriptsCount = registryKeys.length;
|
|
227
|
+
logger.success(`First-party mode enabled for ${scriptsCount} script(s), ${totalDomains} domain(s) proxied (privacy: ${privacyLabel})`);
|
|
228
|
+
}
|
|
229
|
+
const staticPresets = ["static", "github-pages", "cloudflare-pages-static", "netlify-static", "azure-static", "firebase-static"];
|
|
230
|
+
const preset = process.env.NITRO_PRESET || "";
|
|
231
|
+
if (staticPresets.includes(preset)) {
|
|
232
|
+
logger.warn(
|
|
233
|
+
`First-party collection endpoints require a server runtime (detected: ${preset || "static"}).
|
|
234
|
+
Scripts will be bundled, but collection requests will not be proxied.
|
|
64
235
|
|
|
65
|
-
|
|
236
|
+
Options:
|
|
237
|
+
1. Configure platform rewrites (Vercel, Netlify, Cloudflare)
|
|
238
|
+
2. Switch to server-rendered mode (ssr: true)
|
|
239
|
+
3. Disable with firstParty: false
|
|
240
|
+
|
|
241
|
+
See: https://scripts.nuxt.com/docs/guides/first-party#static-hosting`
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
let devtools;
|
|
245
|
+
if (nuxtOptions.dev) {
|
|
246
|
+
const allDomains = /* @__PURE__ */ new Set();
|
|
247
|
+
for (const s of devtoolsScripts) {
|
|
248
|
+
for (const d of s.domains)
|
|
249
|
+
allDomains.add(d);
|
|
250
|
+
}
|
|
251
|
+
devtools = {
|
|
252
|
+
enabled: true,
|
|
253
|
+
proxyPrefix,
|
|
254
|
+
privacyMode: privacyLabel,
|
|
255
|
+
scripts: devtoolsScripts,
|
|
256
|
+
totalDomains: allDomains.size
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
return { proxyPrefix, devtools };
|
|
260
|
+
}
|
|
66
261
|
|
|
67
262
|
const renderedScript = /* @__PURE__ */ new Map();
|
|
68
263
|
const ONE_YEAR_IN_SECONDS = 60 * 60 * 24 * 365;
|
|
69
|
-
|
|
264
|
+
function bundleStorage() {
|
|
70
265
|
const nuxt = tryUseNuxt();
|
|
71
266
|
return createStorage({
|
|
72
267
|
driver: fsDriver({
|
|
73
268
|
base: resolve(nuxt?.options.rootDir || "", "node_modules/.cache/nuxt/scripts")
|
|
74
269
|
})
|
|
75
270
|
});
|
|
76
|
-
}
|
|
271
|
+
}
|
|
77
272
|
function setupPublicAssetStrategy(options = {}) {
|
|
78
|
-
const assetsBaseURL = options.prefix || "/_scripts";
|
|
273
|
+
const assetsBaseURL = options.prefix || "/_scripts/assets";
|
|
79
274
|
const nuxt = useNuxt();
|
|
80
275
|
const storage = bundleStorage();
|
|
81
276
|
addDevServerHandler({
|
|
82
277
|
route: assetsBaseURL,
|
|
83
278
|
handler: lazyEventHandler(async () => {
|
|
84
279
|
return eventHandler(async (event) => {
|
|
85
|
-
const
|
|
86
|
-
const
|
|
280
|
+
const cleanPath = (event.path || "").split("?")[0]?.slice(1) || "";
|
|
281
|
+
const filename = cleanPath;
|
|
282
|
+
const scriptDescriptor = renderedScript.get(join(assetsBaseURL, cleanPath));
|
|
87
283
|
if (!scriptDescriptor || scriptDescriptor instanceof Error)
|
|
88
284
|
throw createError({ statusCode: 404 });
|
|
89
285
|
if (scriptDescriptor.content) {
|
|
@@ -123,242 +319,447 @@ function setupPublicAssetStrategy(options = {}) {
|
|
|
123
319
|
};
|
|
124
320
|
}
|
|
125
321
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
{
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
+
const isStackblitz = provider === "stackblitz";
|
|
364
|
+
async function promptToInstall(name, installCommand, options) {
|
|
365
|
+
if (await resolvePackageJSON(name).catch(() => null))
|
|
366
|
+
return true;
|
|
367
|
+
logger$1.info(`Package ${name} is missing`);
|
|
368
|
+
if (isCI)
|
|
369
|
+
return false;
|
|
370
|
+
if (options.prompt === true || options.prompt !== false && !isStackblitz) {
|
|
371
|
+
const confirm = await logger$1.prompt(`Do you want to install ${name} package?`, {
|
|
372
|
+
type: "confirm",
|
|
373
|
+
name: "confirm",
|
|
374
|
+
initial: true
|
|
375
|
+
});
|
|
376
|
+
if (!confirm)
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
logger$1.info(`Installing ${name}...`);
|
|
380
|
+
try {
|
|
381
|
+
await installCommand();
|
|
382
|
+
logger$1.success(`Installed ${name}`);
|
|
383
|
+
return true;
|
|
384
|
+
} catch (err) {
|
|
385
|
+
logger$1.error(err);
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
const installPrompts = /* @__PURE__ */ new Set();
|
|
390
|
+
function installNuxtModule(name, options) {
|
|
391
|
+
if (installPrompts.has(name))
|
|
392
|
+
return;
|
|
393
|
+
installPrompts.add(name);
|
|
394
|
+
const nuxt = tryUseNuxt();
|
|
395
|
+
if (!nuxt)
|
|
396
|
+
return;
|
|
397
|
+
return promptToInstall(name, async () => {
|
|
398
|
+
const { runCommand } = await import(String("nuxi"));
|
|
399
|
+
await runCommand("module", ["add", name, "--cwd", nuxt.options.rootDir]);
|
|
400
|
+
}, { rootDir: nuxt.options.rootDir, searchPaths: nuxt.options.modulesDir, ...options });
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
function normalizeRegistryConfig(registry) {
|
|
404
|
+
for (const key of Object.keys(registry)) {
|
|
405
|
+
const entry = registry[key];
|
|
406
|
+
if (!entry) {
|
|
407
|
+
delete registry[key];
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
if (entry === true) {
|
|
411
|
+
registry[key] = [{}];
|
|
412
|
+
} else if (entry === "mock") {
|
|
413
|
+
registry[key] = [{}, { trigger: "manual", skipValidation: true }];
|
|
414
|
+
} else if (Array.isArray(entry)) {
|
|
415
|
+
if (!entry[0] && !entry[1]) {
|
|
416
|
+
delete registry[key];
|
|
417
|
+
continue;
|
|
188
418
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
419
|
+
if (!entry[0])
|
|
420
|
+
entry[0] = {};
|
|
421
|
+
} else if (typeof entry === "object") {
|
|
422
|
+
registry[key] = [entry];
|
|
423
|
+
} else {
|
|
424
|
+
delete registry[key];
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
function isVue(id, opts = {}) {
|
|
430
|
+
const { search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
|
|
431
|
+
if (id.endsWith(".vue") && !search) {
|
|
432
|
+
return true;
|
|
433
|
+
}
|
|
434
|
+
if (!search) {
|
|
435
|
+
return false;
|
|
436
|
+
}
|
|
437
|
+
const query = parseQuery(search);
|
|
438
|
+
if (query.nuxt_component) {
|
|
439
|
+
return false;
|
|
440
|
+
}
|
|
441
|
+
if (query.macro && (search === "?macro=true" || !opts.type || opts.type.includes("script"))) {
|
|
442
|
+
return true;
|
|
443
|
+
}
|
|
444
|
+
const type = "setup" in query ? "script" : query.type;
|
|
445
|
+
if (!("vue" in query) || opts.type && !opts.type.includes(type)) {
|
|
446
|
+
return false;
|
|
447
|
+
}
|
|
448
|
+
return true;
|
|
449
|
+
}
|
|
450
|
+
const JS_RE$1 = /\.(?:[cm]?j|t)sx?$/;
|
|
451
|
+
function isJS(id) {
|
|
452
|
+
const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href));
|
|
453
|
+
return JS_RE$1.test(pathname);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
const VUE_RE$1 = /\.vue/;
|
|
457
|
+
function NuxtScriptsCheckScripts() {
|
|
458
|
+
return createUnplugin(() => {
|
|
459
|
+
return {
|
|
460
|
+
name: "nuxt-scripts:check-scripts",
|
|
461
|
+
transform: {
|
|
462
|
+
filter: {
|
|
463
|
+
id: VUE_RE$1
|
|
464
|
+
},
|
|
465
|
+
handler(code, id) {
|
|
466
|
+
if (!isVue(id, { type: ["script"] }))
|
|
467
|
+
return;
|
|
468
|
+
if (!code.includes("useScript"))
|
|
469
|
+
return;
|
|
470
|
+
let nameNode;
|
|
471
|
+
let errorNode;
|
|
472
|
+
parseAndWalk(code, id, (_node) => {
|
|
473
|
+
if (_node.type === "VariableDeclaration" && _node.declarations?.[0]?.id?.type === "ObjectPattern") {
|
|
474
|
+
const objPattern = _node.declarations[0]?.id;
|
|
475
|
+
for (const property of objPattern.properties) {
|
|
476
|
+
if (property.type === "Property" && property.key.type === "Identifier" && property.key.name === "$script" && property.value.type === "Identifier") {
|
|
477
|
+
nameNode = _node;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
if (nameNode) {
|
|
482
|
+
let sequence = _node.type === "SequenceExpression" ? _node : null;
|
|
483
|
+
let assignmentExpression;
|
|
484
|
+
if (_node.type === "VariableDeclaration") {
|
|
485
|
+
if (_node.declarations[0]?.init?.type === "SequenceExpression") {
|
|
486
|
+
sequence = _node.declarations[0]?.init;
|
|
487
|
+
assignmentExpression = _node.declarations[0]?.init?.expressions?.[0];
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
if (sequence && !assignmentExpression) {
|
|
491
|
+
assignmentExpression = sequence.expressions[0]?.type === "AssignmentExpression" ? sequence.expressions[0] : null;
|
|
492
|
+
}
|
|
493
|
+
if (assignmentExpression) {
|
|
494
|
+
const right = assignmentExpression?.right;
|
|
495
|
+
if (right.callee?.name === "_withAsyncContext") {
|
|
496
|
+
if (right.arguments[0]?.body?.name === "$script" || right.arguments[0]?.body?.callee?.object?.name === "$script") {
|
|
497
|
+
errorNode = nameNode;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
if (errorNode) {
|
|
504
|
+
return this.error(new Error("You can't use a top-level await on $script as it will never resolve."));
|
|
505
|
+
}
|
|
506
|
+
}
|
|
198
507
|
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
508
|
+
};
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const WORD_OR_DOLLAR_RE = /[\w$]/;
|
|
513
|
+
const BLANK_CANVAS_DATA_URL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIHWNgAAIABQABNjN9GQAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAAA0lEQVQI12NgYGBgAAAABQABXvMqOgAAAABJRU5ErkJggg==";
|
|
514
|
+
function isPropertyKeyAST(parent, ctx) {
|
|
515
|
+
return parent?.type === "Property" && ctx.key === "key" || parent?.type === "SwitchCase" && ctx.key === "test";
|
|
516
|
+
}
|
|
517
|
+
function matchAndRewrite(value, rewrites) {
|
|
518
|
+
for (const { from, to } of rewrites) {
|
|
519
|
+
const isSuffixMatch = from.startsWith(".");
|
|
520
|
+
const fromSlashIdx = from.indexOf("/");
|
|
521
|
+
const fromHost = fromSlashIdx > 0 ? from.slice(0, fromSlashIdx) : from;
|
|
522
|
+
const fromPath = fromSlashIdx > 0 ? from.slice(fromSlashIdx) : "";
|
|
523
|
+
if (!value.includes(fromHost))
|
|
524
|
+
continue;
|
|
525
|
+
const url = parseURL(value);
|
|
526
|
+
let shouldRewrite = false;
|
|
527
|
+
let rewriteSuffix = "";
|
|
528
|
+
if (url.host) {
|
|
529
|
+
const hostMatches = isSuffixMatch ? url.host.endsWith(fromHost) : url.host === fromHost;
|
|
530
|
+
if (hostMatches) {
|
|
531
|
+
const fullPath = url.pathname + (url.search || "") + (url.hash || "");
|
|
532
|
+
if (fromPath && fullPath.startsWith(fromPath)) {
|
|
533
|
+
shouldRewrite = true;
|
|
534
|
+
rewriteSuffix = fullPath.slice(fromPath.length);
|
|
535
|
+
} else if (!fromPath) {
|
|
536
|
+
shouldRewrite = true;
|
|
537
|
+
rewriteSuffix = fullPath;
|
|
538
|
+
}
|
|
210
539
|
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
540
|
+
} else if (value.startsWith("//")) {
|
|
541
|
+
const hostPart = value.slice(2).split("/")[0];
|
|
542
|
+
const hostMatches = isSuffixMatch ? hostPart?.endsWith(fromHost) ?? false : hostPart === fromHost;
|
|
543
|
+
if (hostMatches) {
|
|
544
|
+
const remainder = value.slice(2 + (hostPart?.length ?? 0));
|
|
545
|
+
if (fromPath && remainder.startsWith(fromPath)) {
|
|
546
|
+
shouldRewrite = true;
|
|
547
|
+
rewriteSuffix = remainder.slice(fromPath.length);
|
|
548
|
+
} else if (!fromPath) {
|
|
549
|
+
shouldRewrite = true;
|
|
550
|
+
rewriteSuffix = remainder;
|
|
551
|
+
}
|
|
222
552
|
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
],
|
|
230
|
-
routes: {
|
|
231
|
-
[`${collectPrefix}/snap/**`]: { proxy: "https://tr.snapchat.com/**" }
|
|
553
|
+
} else if (fromPath && (value.startsWith(from) || isSuffixMatch && value.includes(from))) {
|
|
554
|
+
const domainEnd = value.indexOf(from) + from.length;
|
|
555
|
+
const nextChar = value[domainEnd];
|
|
556
|
+
if (!nextChar || nextChar === "/" || nextChar === "?" || nextChar === "#") {
|
|
557
|
+
shouldRewrite = true;
|
|
558
|
+
rewriteSuffix = value.slice(domainEnd);
|
|
232
559
|
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
560
|
+
}
|
|
561
|
+
if (shouldRewrite) {
|
|
562
|
+
return rewriteSuffix === "/" || rewriteSuffix.startsWith("?") || rewriteSuffix.startsWith("#") ? to + rewriteSuffix : joinURL(to, rewriteSuffix);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
return null;
|
|
566
|
+
}
|
|
567
|
+
const WINDOW_GLOBALS = /* @__PURE__ */ new Set(["window", "self", "globalThis"]);
|
|
568
|
+
const NAVIGATOR_GLOBALS = /* @__PURE__ */ new Set(["navigator"]);
|
|
569
|
+
function resolveToGlobal(name, scopeTracker, depth = 0) {
|
|
570
|
+
if (depth > 10)
|
|
571
|
+
return null;
|
|
572
|
+
const decl = scopeTracker.getDeclaration(name);
|
|
573
|
+
if (!decl)
|
|
574
|
+
return name;
|
|
575
|
+
if (decl instanceof ScopeTrackerFunctionParam)
|
|
576
|
+
return null;
|
|
577
|
+
if (decl instanceof ScopeTrackerVariable) {
|
|
578
|
+
const declarators = decl.variableNode.declarations;
|
|
579
|
+
if (!declarators)
|
|
580
|
+
return null;
|
|
581
|
+
for (const declarator of declarators) {
|
|
582
|
+
const id = declarator.id;
|
|
583
|
+
if (!id || id.name !== name)
|
|
584
|
+
continue;
|
|
585
|
+
const init = declarator.init;
|
|
586
|
+
if (!init)
|
|
587
|
+
return null;
|
|
588
|
+
if (init.type === "Identifier")
|
|
589
|
+
return resolveToGlobal(init.name, scopeTracker, depth + 1);
|
|
590
|
+
if (init.type === "MemberExpression" && init.object?.type === "Identifier") {
|
|
591
|
+
const memberProp = init.computed ? init.property?.type === "Literal" && typeof init.property.value === "string" ? init.property.value : null : init.property?.type === "Identifier" ? init.property.name : null;
|
|
592
|
+
if (!memberProp)
|
|
593
|
+
return null;
|
|
594
|
+
const objGlobal = resolveToGlobal(init.object.name, scopeTracker, depth + 1);
|
|
595
|
+
if (!objGlobal)
|
|
596
|
+
return null;
|
|
597
|
+
if (WINDOW_GLOBALS.has(objGlobal) || objGlobal === "document")
|
|
598
|
+
return memberProp;
|
|
599
|
+
return null;
|
|
242
600
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
601
|
+
return null;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
return null;
|
|
605
|
+
}
|
|
606
|
+
function resolveCalleeTarget(callee, scopeTracker) {
|
|
607
|
+
if (callee?.type !== "MemberExpression")
|
|
608
|
+
return null;
|
|
609
|
+
const propName = callee.computed ? callee.property?.type === "Literal" && typeof callee.property.value === "string" ? callee.property.value : null : callee.property?.name;
|
|
610
|
+
if (!propName)
|
|
611
|
+
return null;
|
|
612
|
+
const obj = callee.object;
|
|
613
|
+
if (!obj || obj.type !== "Identifier")
|
|
614
|
+
return null;
|
|
615
|
+
const resolved = resolveToGlobal(obj.name, scopeTracker);
|
|
616
|
+
if (!resolved)
|
|
617
|
+
return null;
|
|
618
|
+
if (propName === "fetch" && WINDOW_GLOBALS.has(resolved))
|
|
619
|
+
return "fetch";
|
|
620
|
+
if (propName === "sendBeacon" && (NAVIGATOR_GLOBALS.has(resolved) || WINDOW_GLOBALS.has(resolved)))
|
|
621
|
+
return "sendBeacon";
|
|
622
|
+
if (propName === "sendBeacon" && resolved === "navigator")
|
|
623
|
+
return "sendBeacon";
|
|
624
|
+
if (propName === "XMLHttpRequest" && WINDOW_GLOBALS.has(resolved))
|
|
625
|
+
return "XMLHttpRequest";
|
|
626
|
+
if (propName === "Image" && WINDOW_GLOBALS.has(resolved))
|
|
627
|
+
return "Image";
|
|
628
|
+
return null;
|
|
629
|
+
}
|
|
630
|
+
function rewriteScriptUrlsAST(content, filename, rewrites, postProcess, options) {
|
|
631
|
+
const s = new MagicString(content);
|
|
632
|
+
function needsLeadingSpace(start) {
|
|
633
|
+
const prev = content[start - 1];
|
|
634
|
+
return prev && WORD_OR_DOLLAR_RE.test(prev) ? " " : "";
|
|
635
|
+
}
|
|
636
|
+
const scopeTracker = new ScopeTracker({ preserveExitedScopes: true });
|
|
637
|
+
const { program } = parseAndWalk(content, filename, { scopeTracker });
|
|
638
|
+
scopeTracker.freeze();
|
|
639
|
+
walk(program, {
|
|
640
|
+
scopeTracker,
|
|
641
|
+
enter(node, parent, ctx) {
|
|
642
|
+
if (node.type === "Literal" && typeof node.value === "string") {
|
|
643
|
+
const value = node.value;
|
|
644
|
+
const rewritten = matchAndRewrite(value, rewrites);
|
|
645
|
+
if (rewritten === null)
|
|
646
|
+
return;
|
|
647
|
+
const quote = content[node.start];
|
|
648
|
+
if (isPropertyKeyAST(parent, ctx)) {
|
|
649
|
+
s.overwrite(node.start, node.end, quote + rewritten + quote);
|
|
650
|
+
} else {
|
|
651
|
+
s.overwrite(node.start, node.end, `${needsLeadingSpace(node.start)}self.location.origin+${quote}${rewritten}${quote}`);
|
|
652
|
+
}
|
|
262
653
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
654
|
+
if (node.type === "TemplateLiteral") {
|
|
655
|
+
const quasis = node.quasis;
|
|
656
|
+
const expressions = node.expressions;
|
|
657
|
+
if (expressions?.length === 0 && quasis?.length === 1) {
|
|
658
|
+
const value = quasis[0].value?.cooked ?? quasis[0].value?.raw;
|
|
659
|
+
if (typeof value !== "string")
|
|
660
|
+
return;
|
|
661
|
+
const rewritten = matchAndRewrite(value, rewrites);
|
|
662
|
+
if (rewritten === null)
|
|
663
|
+
return;
|
|
664
|
+
if (isPropertyKeyAST(parent, ctx)) {
|
|
665
|
+
s.overwrite(node.start, node.end, `\`${rewritten}\``);
|
|
666
|
+
} else {
|
|
667
|
+
s.overwrite(node.start, node.end, `${needsLeadingSpace(node.start)}self.location.origin+\`${rewritten}\``);
|
|
668
|
+
}
|
|
669
|
+
} else if (expressions?.length > 0 && quasis?.length > 0) {
|
|
670
|
+
const firstQuasi = quasis[0];
|
|
671
|
+
const value = firstQuasi.value?.cooked ?? firstQuasi.value?.raw;
|
|
672
|
+
if (typeof value !== "string" || isPropertyKeyAST(parent, ctx))
|
|
673
|
+
return;
|
|
674
|
+
const rewritten = matchAndRewrite(value, rewrites);
|
|
675
|
+
if (rewritten === null)
|
|
676
|
+
return;
|
|
677
|
+
s.overwrite(node.start, firstQuasi.end, `${needsLeadingSpace(node.start)}self.location.origin+\`${rewritten}`);
|
|
678
|
+
}
|
|
275
679
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
680
|
+
if (node.type === "CallExpression" && !options?.skipApiRewrites) {
|
|
681
|
+
const callee = node.callee;
|
|
682
|
+
const canvasPropName = callee?.type === "MemberExpression" ? callee.computed ? callee.property?.type === "Literal" && typeof callee.property.value === "string" ? callee.property.value : null : callee.property?.name : null;
|
|
683
|
+
if (canvasPropName === "toDataURL" && callee.object) {
|
|
684
|
+
const blankCanvas = `"${BLANK_CANVAS_DATA_URL}"`;
|
|
685
|
+
if (callee.object.type === "Identifier") {
|
|
686
|
+
const decl = scopeTracker.getDeclaration(callee.object.name);
|
|
687
|
+
if (decl instanceof ScopeTrackerFunction || decl instanceof ScopeTrackerIdentifier) ; else {
|
|
688
|
+
s.overwrite(node.start, node.end, blankCanvas);
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
} else {
|
|
692
|
+
s.overwrite(node.start, node.end, blankCanvas);
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
if (canvasPropName === "getExtension") {
|
|
697
|
+
const args = node.arguments;
|
|
698
|
+
if (args?.length === 1 && args[0]?.type === "Literal" && args[0].value === "WEBGL_debug_renderer_info") {
|
|
699
|
+
s.overwrite(node.start, node.end, "null");
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
if (callee?.type === "Identifier" && callee.name === "fetch") {
|
|
704
|
+
if (!scopeTracker.getDeclaration("fetch"))
|
|
705
|
+
s.overwrite(callee.start, callee.end, "__nuxtScripts.fetch");
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
const target = resolveCalleeTarget(callee, scopeTracker);
|
|
709
|
+
if (target === "fetch" || target === "sendBeacon") {
|
|
710
|
+
s.overwrite(callee.start, callee.end, `__nuxtScripts.${target}`);
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
if (callee?.type === "MemberExpression" && !callee.computed && callee.property?.name === "sendBeacon" && callee.object?.type === "Identifier") {
|
|
714
|
+
const resolved = resolveToGlobal(callee.object.name, scopeTracker);
|
|
715
|
+
if (resolved === null) {
|
|
716
|
+
s.overwrite(callee.start, callee.end, "__nuxtScripts.sendBeacon");
|
|
717
|
+
}
|
|
718
|
+
}
|
|
304
719
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
720
|
+
if (node.type === "NewExpression" && !options?.skipApiRewrites) {
|
|
721
|
+
const callee = node.callee;
|
|
722
|
+
if (callee?.type === "Identifier" && callee.name === "XMLHttpRequest") {
|
|
723
|
+
if (!scopeTracker.getDeclaration("XMLHttpRequest"))
|
|
724
|
+
s.overwrite(callee.start, callee.end, "__nuxtScripts.XMLHttpRequest");
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
if (callee?.type === "Identifier" && callee.name === "Image") {
|
|
728
|
+
if (!scopeTracker.getDeclaration("Image"))
|
|
729
|
+
s.overwrite(callee.start, callee.end, "__nuxtScripts.Image");
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
const target = resolveCalleeTarget(callee, scopeTracker);
|
|
733
|
+
if (target === "XMLHttpRequest" || target === "Image") {
|
|
734
|
+
s.overwrite(callee.start, callee.end, `__nuxtScripts.${target}`);
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
if (callee?.type === "MemberExpression" && callee.object?.type === "Identifier") {
|
|
738
|
+
const propName = callee.computed ? callee.property?.type === "Literal" && typeof callee.property.value === "string" ? callee.property.value : null : callee.property?.name;
|
|
739
|
+
if (propName === "XMLHttpRequest" || propName === "Image") {
|
|
740
|
+
const resolved = resolveToGlobal(callee.object.name, scopeTracker);
|
|
741
|
+
if (resolved === null) {
|
|
742
|
+
s.overwrite(callee.start, callee.end, `__nuxtScripts.${propName}`);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
328
746
|
}
|
|
329
747
|
}
|
|
748
|
+
});
|
|
749
|
+
let output = s.toString();
|
|
750
|
+
if (postProcess) {
|
|
751
|
+
output = postProcess(output, rewrites);
|
|
330
752
|
}
|
|
331
|
-
return
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
function isVue(id, opts = {}) {
|
|
335
|
-
const { search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
|
|
336
|
-
if (id.endsWith(".vue") && !search) {
|
|
337
|
-
return true;
|
|
338
|
-
}
|
|
339
|
-
if (!search) {
|
|
340
|
-
return false;
|
|
341
|
-
}
|
|
342
|
-
const query = parseQuery(search);
|
|
343
|
-
if (query.nuxt_component) {
|
|
344
|
-
return false;
|
|
345
|
-
}
|
|
346
|
-
if (query.macro && (search === "?macro=true" || !opts.type || opts.type.includes("script"))) {
|
|
347
|
-
return true;
|
|
348
|
-
}
|
|
349
|
-
const type = "setup" in query ? "script" : query.type;
|
|
350
|
-
if (!("vue" in query) || opts.type && !opts.type.includes(type)) {
|
|
351
|
-
return false;
|
|
352
|
-
}
|
|
353
|
-
return true;
|
|
354
|
-
}
|
|
355
|
-
const JS_RE = /\.(?:[cm]?j|t)sx?$/;
|
|
356
|
-
function isJS(id) {
|
|
357
|
-
const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href));
|
|
358
|
-
return JS_RE.test(pathname);
|
|
753
|
+
return output;
|
|
359
754
|
}
|
|
360
755
|
|
|
361
756
|
const SEVEN_DAYS_IN_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
757
|
+
const PROTOCOL_RELATIVE_RE = /^\/\//;
|
|
758
|
+
const VUE_RE = /\.vue/;
|
|
759
|
+
const JS_RE = /\.[cm]?[jt]sx?$/;
|
|
760
|
+
const TEST_RE = /\.(?:test|spec)\./;
|
|
761
|
+
const UPPERCASE_RE = /^[A-Z]$/;
|
|
762
|
+
const USE_SCRIPT_RE = /^useScript/;
|
|
362
763
|
function calculateIntegrity(content, algorithm = "sha384") {
|
|
363
764
|
const hash = createHash(algorithm).update(content).digest("base64");
|
|
364
765
|
return `${algorithm}-${hash}`;
|
|
@@ -371,14 +772,12 @@ async function isCacheExpired(storage, filename, cacheMaxAge = SEVEN_DAYS_IN_MS)
|
|
|
371
772
|
}
|
|
372
773
|
return Date.now() - meta.timestamp > cacheMaxAge;
|
|
373
774
|
}
|
|
374
|
-
function normalizeScriptData(src, assetsBaseURL = "/_scripts") {
|
|
775
|
+
function normalizeScriptData(src, assetsBaseURL = "/_scripts/assets") {
|
|
375
776
|
if (hasProtocol(src, { acceptRelative: true })) {
|
|
376
|
-
src = src.replace(
|
|
777
|
+
src = src.replace(PROTOCOL_RELATIVE_RE, "https://");
|
|
377
778
|
const url = parseURL(src);
|
|
378
|
-
const
|
|
379
|
-
|
|
380
|
-
// force an extension
|
|
381
|
-
].filter(Boolean).join("-");
|
|
779
|
+
const h = hash(url);
|
|
780
|
+
const file = `${h.startsWith("-") ? `_${h.slice(1)}` : h}.js`;
|
|
382
781
|
const nuxt = tryUseNuxt();
|
|
383
782
|
const cdnURL = nuxt?.options.runtimeConfig?.app?.cdnURL || nuxt?.options.app?.cdnURL || "";
|
|
384
783
|
const baseURL = cdnURL || nuxt?.options.app.baseURL || "";
|
|
@@ -387,7 +786,7 @@ function normalizeScriptData(src, assetsBaseURL = "/_scripts") {
|
|
|
387
786
|
return { url: src };
|
|
388
787
|
}
|
|
389
788
|
async function downloadScript(opts, renderedScript, fetchOptions, cacheMaxAge) {
|
|
390
|
-
const { src, url, filename, forceDownload, integrity, proxyRewrites } = opts;
|
|
789
|
+
const { src, url, filename, forceDownload, integrity, proxyRewrites, postProcess, skipApiRewrites } = opts;
|
|
391
790
|
if (src === url || !filename) {
|
|
392
791
|
return;
|
|
393
792
|
}
|
|
@@ -425,7 +824,7 @@ async function downloadScript(opts, renderedScript, fetchOptions, cacheMaxAge) {
|
|
|
425
824
|
await storage.setItemRaw(`bundle:${filename}`, res);
|
|
426
825
|
if (proxyRewrites?.length && res) {
|
|
427
826
|
const content = res.toString("utf-8");
|
|
428
|
-
const rewritten =
|
|
827
|
+
const rewritten = rewriteScriptUrlsAST(content, filename || "script.js", proxyRewrites, postProcess, { skipApiRewrites });
|
|
429
828
|
res = Buffer.from(rewritten, "utf-8");
|
|
430
829
|
logger.debug(`Rewrote ${proxyRewrites.length} URL patterns in ${filename}`);
|
|
431
830
|
}
|
|
@@ -482,8 +881,8 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
482
881
|
transform: {
|
|
483
882
|
filter: {
|
|
484
883
|
id: {
|
|
485
|
-
include: [
|
|
486
|
-
exclude: [
|
|
884
|
+
include: [VUE_RE, JS_RE],
|
|
885
|
+
exclude: [TEST_RE]
|
|
487
886
|
}
|
|
488
887
|
},
|
|
489
888
|
async handler(code, id) {
|
|
@@ -493,11 +892,11 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
493
892
|
return;
|
|
494
893
|
const s = new MagicString(code);
|
|
495
894
|
const deferredOps = [];
|
|
496
|
-
parseAndWalk(code, id,
|
|
895
|
+
parseAndWalk(code, id, (_node) => {
|
|
497
896
|
const calleeName = _node.callee?.name;
|
|
498
897
|
if (!calleeName)
|
|
499
898
|
return;
|
|
500
|
-
const isValidCallee = calleeName === "useScript" || calleeName?.startsWith("useScript") &&
|
|
899
|
+
const isValidCallee = calleeName === "useScript" || calleeName?.startsWith("useScript") && UPPERCASE_RE.test(calleeName?.charAt(9)) && !calleeName.startsWith("useScriptTrigger") && !calleeName.startsWith("useScriptEvent");
|
|
501
900
|
if (_node.type === "CallExpression" && _node.callee.type === "Identifier" && isValidCallee) {
|
|
502
901
|
const fnName = _node.callee?.name;
|
|
503
902
|
const node = _node;
|
|
@@ -505,7 +904,7 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
505
904
|
let src;
|
|
506
905
|
let registryKey;
|
|
507
906
|
if (fnName !== "useScript") {
|
|
508
|
-
const baseName = fnName.replace(
|
|
907
|
+
const baseName = fnName.replace(USE_SCRIPT_RE, "");
|
|
509
908
|
registryKey = baseName.length > 0 ? baseName.charAt(0).toLowerCase() + baseName.slice(1) : void 0;
|
|
510
909
|
}
|
|
511
910
|
if (fnName === "useScript") {
|
|
@@ -625,11 +1024,17 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
625
1024
|
const { url: _url, filename } = normalizeScriptData(src, options.assetsBaseURL);
|
|
626
1025
|
const script = options.scripts?.find((s2) => s2.import.name === fnName);
|
|
627
1026
|
const proxyConfigKey = script?.proxy !== false ? script?.proxy || registryKey : void 0;
|
|
628
|
-
const
|
|
1027
|
+
const proxyConfig = !firstPartyOptOut && proxyConfigKey ? options.proxyConfigs?.[proxyConfigKey] : void 0;
|
|
1028
|
+
const proxyRewrites = proxyConfig?.domains?.map((domain) => ({
|
|
1029
|
+
from: domain,
|
|
1030
|
+
to: `${options.proxyPrefix}/${domain}`
|
|
1031
|
+
}));
|
|
1032
|
+
const postProcess = proxyConfig?.postProcess;
|
|
1033
|
+
const skipApiRewrites = !!(registryKey && options.partytownScripts?.has(registryKey));
|
|
629
1034
|
deferredOps.push(async () => {
|
|
630
1035
|
let url = _url;
|
|
631
1036
|
try {
|
|
632
|
-
await downloadScript({ src, url, filename, forceDownload, proxyRewrites, integrity: options.integrity }, renderedScript, options.fetchOptions, options.cacheMaxAge);
|
|
1037
|
+
await downloadScript({ src, url, filename, forceDownload, proxyRewrites, postProcess, integrity: options.integrity, skipApiRewrites }, renderedScript, options.fetchOptions, options.cacheMaxAge);
|
|
633
1038
|
} catch (e) {
|
|
634
1039
|
if (options.fallbackOnSrcOnBundleFail) {
|
|
635
1040
|
logger.warn(`[Nuxt Scripts: Bundle Transformer] Failed to bundle ${src}. Fallback to remote loading.`);
|
|
@@ -685,7 +1090,7 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
685
1090
|
s.appendRight(node.arguments[0].start + 1, ` scriptInput: { src: '${url}'${integrityProps} }, `);
|
|
686
1091
|
}
|
|
687
1092
|
} else {
|
|
688
|
-
s.
|
|
1093
|
+
s.overwrite(node.callee.end, node.end, `({ scriptInput: { src: '${url}'${integrityProps} } })`);
|
|
689
1094
|
}
|
|
690
1095
|
}
|
|
691
1096
|
});
|
|
@@ -709,101 +1114,7 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
709
1114
|
});
|
|
710
1115
|
}
|
|
711
1116
|
|
|
712
|
-
const
|
|
713
|
-
async function promptToInstall(name, installCommand, options) {
|
|
714
|
-
if (await resolvePackageJSON(name).catch(() => null))
|
|
715
|
-
return true;
|
|
716
|
-
logger$1.info(`Package ${name} is missing`);
|
|
717
|
-
if (isCI)
|
|
718
|
-
return false;
|
|
719
|
-
if (options.prompt === true || options.prompt !== false && !isStackblitz) {
|
|
720
|
-
const confirm = await logger$1.prompt(`Do you want to install ${name} package?`, {
|
|
721
|
-
type: "confirm",
|
|
722
|
-
name: "confirm",
|
|
723
|
-
initial: true
|
|
724
|
-
});
|
|
725
|
-
if (!confirm)
|
|
726
|
-
return false;
|
|
727
|
-
}
|
|
728
|
-
logger$1.info(`Installing ${name}...`);
|
|
729
|
-
try {
|
|
730
|
-
await installCommand();
|
|
731
|
-
logger$1.success(`Installed ${name}`);
|
|
732
|
-
return true;
|
|
733
|
-
} catch (err) {
|
|
734
|
-
logger$1.error(err);
|
|
735
|
-
return false;
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
const installPrompts = /* @__PURE__ */ new Set();
|
|
739
|
-
function installNuxtModule(name, options) {
|
|
740
|
-
if (installPrompts.has(name))
|
|
741
|
-
return;
|
|
742
|
-
installPrompts.add(name);
|
|
743
|
-
const nuxt = tryUseNuxt();
|
|
744
|
-
if (!nuxt)
|
|
745
|
-
return;
|
|
746
|
-
return promptToInstall(name, async () => {
|
|
747
|
-
const { runCommand } = await import(String("nuxi"));
|
|
748
|
-
await runCommand("module", ["add", name, "--cwd", nuxt.options.rootDir]);
|
|
749
|
-
}, { rootDir: nuxt.options.rootDir, searchPaths: nuxt.options.modulesDir, ...options });
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
function NuxtScriptsCheckScripts() {
|
|
753
|
-
return createUnplugin(() => {
|
|
754
|
-
return {
|
|
755
|
-
name: "nuxt-scripts:check-scripts",
|
|
756
|
-
transform: {
|
|
757
|
-
filter: {
|
|
758
|
-
id: /\.vue/
|
|
759
|
-
},
|
|
760
|
-
handler(code, id) {
|
|
761
|
-
if (!isVue(id, { type: ["script"] }))
|
|
762
|
-
return;
|
|
763
|
-
if (!code.includes("useScript"))
|
|
764
|
-
return;
|
|
765
|
-
let nameNode;
|
|
766
|
-
let errorNode;
|
|
767
|
-
parseAndWalk(code, id, function(_node) {
|
|
768
|
-
if (_node.type === "VariableDeclaration" && _node.declarations?.[0]?.id?.type === "ObjectPattern") {
|
|
769
|
-
const objPattern = _node.declarations[0]?.id;
|
|
770
|
-
for (const property of objPattern.properties) {
|
|
771
|
-
if (property.type === "Property" && property.key.type === "Identifier" && property.key.name === "$script" && property.value.type === "Identifier") {
|
|
772
|
-
nameNode = _node;
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
}
|
|
776
|
-
if (nameNode) {
|
|
777
|
-
let sequence = _node.type === "SequenceExpression" ? _node : null;
|
|
778
|
-
let assignmentExpression;
|
|
779
|
-
if (_node.type === "VariableDeclaration") {
|
|
780
|
-
if (_node.declarations[0]?.init?.type === "SequenceExpression") {
|
|
781
|
-
sequence = _node.declarations[0]?.init;
|
|
782
|
-
assignmentExpression = _node.declarations[0]?.init?.expressions?.[0];
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
if (sequence && !assignmentExpression) {
|
|
786
|
-
assignmentExpression = sequence.expressions[0]?.type === "AssignmentExpression" ? sequence.expressions[0] : null;
|
|
787
|
-
}
|
|
788
|
-
if (assignmentExpression) {
|
|
789
|
-
const right = assignmentExpression?.right;
|
|
790
|
-
if (right.callee?.name === "_withAsyncContext") {
|
|
791
|
-
if (right.arguments[0]?.body?.name === "$script" || right.arguments[0]?.body?.callee?.object?.name === "$script") {
|
|
792
|
-
errorNode = nameNode;
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
});
|
|
798
|
-
if (errorNode) {
|
|
799
|
-
return this.error(new Error("You can't use a top-level await on $script as it will never resolve."));
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
};
|
|
804
|
-
});
|
|
805
|
-
}
|
|
806
|
-
|
|
1117
|
+
const TRIGGER_PLACEHOLDER_RE = /"__TRIGGER_PLACEHOLDER__"/g;
|
|
807
1118
|
function registerTypeTemplates({ nuxt, config, newScripts }) {
|
|
808
1119
|
addTypeTemplate({
|
|
809
1120
|
filename: "types/nuxt-scripts-augments.d.ts",
|
|
@@ -815,7 +1126,7 @@ function registerTypeTemplates({ nuxt, config, newScripts }) {
|
|
|
815
1126
|
let augments = `// Generated by @nuxt/scripts
|
|
816
1127
|
declare module '#app' {
|
|
817
1128
|
interface NuxtApp {
|
|
818
|
-
$scripts: Record<${[...Object.keys(config.globals || {}), ...Object.keys(config.registry || {})].map((k) => `'${k}'`)
|
|
1129
|
+
$scripts: Record<${[...[...Object.keys(config.globals || {}), ...Object.keys(config.registry || {})].map((k) => `'${k}'`), ...["string"]].join(" | ")}, import('#nuxt-scripts/types').UseScriptContext<any> | undefined>
|
|
819
1130
|
_scripts: Record<string, import('#nuxt-scripts/types').NuxtDevToolsScriptInstance>
|
|
820
1131
|
}
|
|
821
1132
|
interface RuntimeNuxtHooks {
|
|
@@ -896,28 +1207,30 @@ function templatePlugin(config, registry) {
|
|
|
896
1207
|
let needsInteractionImport = false;
|
|
897
1208
|
let needsServiceWorkerImport = false;
|
|
898
1209
|
for (const [k, c] of Object.entries(config.registry || {})) {
|
|
899
|
-
|
|
1210
|
+
if (c === false)
|
|
1211
|
+
continue;
|
|
1212
|
+
const importDefinition = registry.find((i) => i.import.name.toLowerCase() === `usescript${k.toLowerCase()}`);
|
|
900
1213
|
if (importDefinition) {
|
|
901
1214
|
resolvedRegistryKeys.push(k);
|
|
902
1215
|
imports.unshift(`import { ${importDefinition.import.name} } from '${importDefinition.import.from}'`);
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
const
|
|
907
|
-
const scriptOptions = { ...c[1] };
|
|
908
|
-
const triggerResolved = resolveTriggerForTemplate(scriptOptions?.trigger);
|
|
1216
|
+
const [input, scriptOptions] = c;
|
|
1217
|
+
if (scriptOptions) {
|
|
1218
|
+
const opts = { ...scriptOptions };
|
|
1219
|
+
const triggerResolved = resolveTriggerForTemplate(opts.trigger);
|
|
909
1220
|
if (triggerResolved) {
|
|
910
|
-
|
|
911
|
-
if (triggerResolved.includes("useScriptTriggerIdleTimeout"))
|
|
912
|
-
|
|
913
|
-
if (triggerResolved.includes("
|
|
1221
|
+
opts.trigger = "__TRIGGER_PLACEHOLDER__";
|
|
1222
|
+
if (triggerResolved.includes("useScriptTriggerIdleTimeout"))
|
|
1223
|
+
needsIdleTimeoutImport = true;
|
|
1224
|
+
if (triggerResolved.includes("useScriptTriggerInteraction"))
|
|
1225
|
+
needsInteractionImport = true;
|
|
1226
|
+
if (triggerResolved.includes("useScriptTriggerServiceWorker"))
|
|
1227
|
+
needsServiceWorkerImport = true;
|
|
914
1228
|
}
|
|
915
|
-
const args = { ...input, scriptOptions };
|
|
916
|
-
const argsJson = triggerResolved ? JSON.stringify(args).replace(
|
|
1229
|
+
const args = { ...input, scriptOptions: opts };
|
|
1230
|
+
const argsJson = triggerResolved ? JSON.stringify(args).replace(TRIGGER_PLACEHOLDER_RE, triggerResolved) : JSON.stringify(args);
|
|
917
1231
|
inits.push(`const ${k} = ${importDefinition.import.name}(${argsJson})`);
|
|
918
1232
|
} else {
|
|
919
|
-
const
|
|
920
|
-
inits.push(`const ${k} = ${importDefinition.import.name}(${JSON.stringify(args)})`);
|
|
1233
|
+
inits.push(`const ${k} = ${importDefinition.import.name}(${JSON.stringify(input)})`);
|
|
921
1234
|
}
|
|
922
1235
|
}
|
|
923
1236
|
}
|
|
@@ -928,11 +1241,14 @@ function templatePlugin(config, registry) {
|
|
|
928
1241
|
const options = c[1];
|
|
929
1242
|
const triggerResolved = resolveTriggerForTemplate(options?.trigger);
|
|
930
1243
|
if (triggerResolved) {
|
|
931
|
-
if (triggerResolved.includes("useScriptTriggerIdleTimeout"))
|
|
932
|
-
|
|
933
|
-
if (triggerResolved.includes("
|
|
1244
|
+
if (triggerResolved.includes("useScriptTriggerIdleTimeout"))
|
|
1245
|
+
needsIdleTimeoutImport = true;
|
|
1246
|
+
if (triggerResolved.includes("useScriptTriggerInteraction"))
|
|
1247
|
+
needsInteractionImport = true;
|
|
1248
|
+
if (triggerResolved.includes("useScriptTriggerServiceWorker"))
|
|
1249
|
+
needsServiceWorkerImport = true;
|
|
934
1250
|
const resolvedOptions = { ...options, trigger: "__TRIGGER_PLACEHOLDER__" };
|
|
935
|
-
const optionsJson = JSON.stringify(resolvedOptions).replace(
|
|
1251
|
+
const optionsJson = JSON.stringify(resolvedOptions).replace(TRIGGER_PLACEHOLDER_RE, triggerResolved);
|
|
936
1252
|
inits.push(`const ${k} = useScript(${JSON.stringify({ key: k, ...typeof c[0] === "string" ? { src: c[0] } : c[0] })}, { ...${optionsJson}, use: () => ({ ${k}: window.${k} }) })`);
|
|
937
1253
|
} else {
|
|
938
1254
|
inits.push(`const ${k} = useScript(${JSON.stringify({ key: k, ...typeof c[0] === "string" ? { src: c[0] } : c[0] })}, { ...${JSON.stringify(c[1])}, use: () => ({ ${k}: window.${k} }) })`);
|
|
@@ -940,11 +1256,14 @@ function templatePlugin(config, registry) {
|
|
|
940
1256
|
} else if (typeof c === "object" && c !== null) {
|
|
941
1257
|
const triggerResolved = resolveTriggerForTemplate(c.trigger);
|
|
942
1258
|
if (triggerResolved) {
|
|
943
|
-
if (triggerResolved.includes("useScriptTriggerIdleTimeout"))
|
|
944
|
-
|
|
945
|
-
if (triggerResolved.includes("
|
|
1259
|
+
if (triggerResolved.includes("useScriptTriggerIdleTimeout"))
|
|
1260
|
+
needsIdleTimeoutImport = true;
|
|
1261
|
+
if (triggerResolved.includes("useScriptTriggerInteraction"))
|
|
1262
|
+
needsInteractionImport = true;
|
|
1263
|
+
if (triggerResolved.includes("useScriptTriggerServiceWorker"))
|
|
1264
|
+
needsServiceWorkerImport = true;
|
|
946
1265
|
const resolvedOptions = { ...c, trigger: "__TRIGGER_PLACEHOLDER__" };
|
|
947
|
-
const argsJson = JSON.stringify({ key: k, ...resolvedOptions }).replace(
|
|
1266
|
+
const argsJson = JSON.stringify({ key: k, ...resolvedOptions }).replace(TRIGGER_PLACEHOLDER_RE, triggerResolved);
|
|
948
1267
|
inits.push(`const ${k} = useScript(${argsJson}, { use: () => ({ ${k}: window.${k} }) })`);
|
|
949
1268
|
} else {
|
|
950
1269
|
inits.push(`const ${k} = useScript(${JSON.stringify({ key: k, ...c })}, { use: () => ({ ${k}: window.${k} }) })`);
|
|
@@ -973,19 +1292,106 @@ function templatePlugin(config, registry) {
|
|
|
973
1292
|
` parallel: true,`,
|
|
974
1293
|
` setup() {`,
|
|
975
1294
|
...inits.map((i) => ` ${i}`),
|
|
976
|
-
` return { provide: {
|
|
1295
|
+
` return { provide: { scripts: { ${[...Object.keys(config.globals || {}), ...resolvedRegistryKeys].join(", ")} } } }`,
|
|
977
1296
|
` }`,
|
|
978
1297
|
`})`
|
|
979
1298
|
].join("\n");
|
|
980
1299
|
}
|
|
981
1300
|
|
|
1301
|
+
const SELF_CLOSING_SCRIPT_RE = /<((?:Script[A-Z]|script-)\w[\w-]*)\b([^>]*?)\/\s*>/g;
|
|
1302
|
+
function fixSelfClosingScriptComponents(nuxt) {
|
|
1303
|
+
function expandTags(content) {
|
|
1304
|
+
SELF_CLOSING_SCRIPT_RE.lastIndex = 0;
|
|
1305
|
+
if (!SELF_CLOSING_SCRIPT_RE.test(content))
|
|
1306
|
+
return null;
|
|
1307
|
+
SELF_CLOSING_SCRIPT_RE.lastIndex = 0;
|
|
1308
|
+
return content.replace(SELF_CLOSING_SCRIPT_RE, (_, tag, attrs) => `<${tag}${attrs.trimEnd()}></${tag}>`);
|
|
1309
|
+
}
|
|
1310
|
+
function fixFile(filePath) {
|
|
1311
|
+
if (!existsSync(filePath))
|
|
1312
|
+
return;
|
|
1313
|
+
const content = readFileSync(filePath, "utf-8");
|
|
1314
|
+
const fixed = expandTags(content);
|
|
1315
|
+
if (fixed)
|
|
1316
|
+
nuxt.vfs[filePath] = fixed;
|
|
1317
|
+
}
|
|
1318
|
+
function scanDir(dir) {
|
|
1319
|
+
if (!existsSync(dir))
|
|
1320
|
+
return;
|
|
1321
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
1322
|
+
const fullPath = resolve(dir, entry.name);
|
|
1323
|
+
if (entry.isDirectory())
|
|
1324
|
+
scanDir(fullPath);
|
|
1325
|
+
else if (entry.name.endsWith(".vue"))
|
|
1326
|
+
fixFile(fullPath);
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
const pagesDirs = /* @__PURE__ */ new Set();
|
|
1330
|
+
for (const layer of nuxt.options._layers) {
|
|
1331
|
+
pagesDirs.add(resolve(
|
|
1332
|
+
layer.config.srcDir,
|
|
1333
|
+
layer.config.dir?.pages || "pages"
|
|
1334
|
+
));
|
|
1335
|
+
}
|
|
1336
|
+
for (const dir of pagesDirs) scanDir(dir);
|
|
1337
|
+
if (nuxt.options.dev) {
|
|
1338
|
+
nuxt.hook("builder:watch", (_event, relativePath) => {
|
|
1339
|
+
if (!relativePath.endsWith(".vue"))
|
|
1340
|
+
return;
|
|
1341
|
+
for (const layer of nuxt.options._layers) {
|
|
1342
|
+
const fullPath = resolve(layer.config.srcDir, relativePath);
|
|
1343
|
+
for (const dir of pagesDirs) {
|
|
1344
|
+
if (fullPath.startsWith(`${dir}/`)) {
|
|
1345
|
+
fixFile(fullPath);
|
|
1346
|
+
return;
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
});
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
const REGISTRY_ENV_DEFAULTS = {
|
|
1354
|
+
bingUet: { id: "" },
|
|
1355
|
+
clarity: { id: "" },
|
|
1356
|
+
cloudflareWebAnalytics: { token: "" },
|
|
1357
|
+
crisp: { id: "" },
|
|
1358
|
+
databuddyAnalytics: { clientId: "" },
|
|
1359
|
+
fathomAnalytics: { site: "" },
|
|
1360
|
+
googleAdsense: { client: "" },
|
|
1361
|
+
googleAnalytics: { id: "" },
|
|
1362
|
+
googleMaps: { apiKey: "" },
|
|
1363
|
+
googleRecaptcha: { siteKey: "" },
|
|
1364
|
+
googleSignIn: { clientId: "" },
|
|
1365
|
+
googleTagManager: { id: "" },
|
|
1366
|
+
hotjar: { id: "" },
|
|
1367
|
+
intercom: { app_id: "" },
|
|
1368
|
+
matomoAnalytics: { matomoUrl: "" },
|
|
1369
|
+
mixpanelAnalytics: { token: "" },
|
|
1370
|
+
metaPixel: { id: "" },
|
|
1371
|
+
paypal: { clientId: "" },
|
|
1372
|
+
plausibleAnalytics: { domain: "" },
|
|
1373
|
+
posthog: { apiKey: "" },
|
|
1374
|
+
redditPixel: { id: "" },
|
|
1375
|
+
rybbitAnalytics: { siteId: "" },
|
|
1376
|
+
segment: { writeKey: "" },
|
|
1377
|
+
snapchatPixel: { id: "" },
|
|
1378
|
+
stripe: {},
|
|
1379
|
+
tiktokPixel: { id: "" },
|
|
1380
|
+
umamiAnalytics: { websiteId: "" },
|
|
1381
|
+
vercelAnalytics: {},
|
|
1382
|
+
xPixel: { id: "" }
|
|
1383
|
+
};
|
|
1384
|
+
const UPPER_RE = /([A-Z])/g;
|
|
1385
|
+
const toScreamingSnake = (s) => s.replace(UPPER_RE, "_$1").toUpperCase();
|
|
982
1386
|
const PARTYTOWN_FORWARDS = {
|
|
1387
|
+
bingUet: ["uetq.push"],
|
|
983
1388
|
googleAnalytics: ["dataLayer.push", "gtag"],
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
1389
|
+
plausibleAnalytics: ["plausible"],
|
|
1390
|
+
fathomAnalytics: ["fathom", "fathom.trackEvent", "fathom.trackPageview"],
|
|
1391
|
+
umamiAnalytics: ["umami", "umami.track"],
|
|
1392
|
+
matomoAnalytics: ["_paq.push"],
|
|
988
1393
|
segment: ["analytics", "analytics.track", "analytics.page", "analytics.identify"],
|
|
1394
|
+
mixpanelAnalytics: ["mixpanel", "mixpanel.init", "mixpanel.track", "mixpanel.identify", "mixpanel.people.set", "mixpanel.reset", "mixpanel.register"],
|
|
989
1395
|
metaPixel: ["fbq"],
|
|
990
1396
|
xPixel: ["twq"],
|
|
991
1397
|
tiktokPixel: ["ttq.track", "ttq.page", "ttq.identify"],
|
|
@@ -1039,39 +1445,51 @@ const module$1 = defineNuxtModule({
|
|
|
1039
1445
|
if (unheadVersion?.startsWith("1")) {
|
|
1040
1446
|
logger.error(`Nuxt Scripts requires Unhead >= 2, you are using v${unheadVersion}. Please run \`nuxi upgrade --clean\` to upgrade...`);
|
|
1041
1447
|
}
|
|
1448
|
+
if (config.registry) {
|
|
1449
|
+
normalizeRegistryConfig(config.registry);
|
|
1450
|
+
nuxt.options.runtimeConfig.public = nuxt.options.runtimeConfig.public || {};
|
|
1451
|
+
const registryWithDefaults = {};
|
|
1452
|
+
for (const [key, entry] of Object.entries(config.registry)) {
|
|
1453
|
+
if (entry === false)
|
|
1454
|
+
continue;
|
|
1455
|
+
const input = entry[0];
|
|
1456
|
+
const envDefaults = REGISTRY_ENV_DEFAULTS[key];
|
|
1457
|
+
if (!envDefaults) {
|
|
1458
|
+
registryWithDefaults[key] = input;
|
|
1459
|
+
continue;
|
|
1460
|
+
}
|
|
1461
|
+
const envResolved = {};
|
|
1462
|
+
for (const [field, defaultValue] of Object.entries(envDefaults)) {
|
|
1463
|
+
const envKey = `NUXT_PUBLIC_SCRIPTS_${toScreamingSnake(key)}_${toScreamingSnake(field)}`;
|
|
1464
|
+
envResolved[field] = process.env[envKey] || defaultValue;
|
|
1465
|
+
}
|
|
1466
|
+
registryWithDefaults[key] = defu(input, envResolved);
|
|
1467
|
+
}
|
|
1468
|
+
nuxt.options.runtimeConfig.public.scripts = defu(
|
|
1469
|
+
nuxt.options.runtimeConfig.public.scripts || {},
|
|
1470
|
+
registryWithDefaults
|
|
1471
|
+
);
|
|
1472
|
+
}
|
|
1473
|
+
const googleMapsEnabled = config.googleStaticMapsProxy?.enabled || !!config.registry?.googleMaps;
|
|
1042
1474
|
nuxt.options.runtimeConfig["nuxt-scripts"] = {
|
|
1043
1475
|
version,
|
|
1044
1476
|
// Private proxy config with API key (server-side only)
|
|
1045
|
-
googleStaticMapsProxy:
|
|
1046
|
-
swTemplate: readFileSync(await resolvePath("./runtime/sw/proxy-sw.template.js"), "utf-8")
|
|
1477
|
+
googleStaticMapsProxy: googleMapsEnabled ? { apiKey: nuxt.options.runtimeConfig.public.scripts?.googleMaps?.apiKey } : void 0
|
|
1047
1478
|
};
|
|
1048
1479
|
nuxt.options.runtimeConfig.public["nuxt-scripts"] = {
|
|
1049
1480
|
// expose for devtools
|
|
1050
1481
|
version: nuxt.options.dev ? version : void 0,
|
|
1051
1482
|
defaultScriptOptions: config.defaultScriptOptions,
|
|
1052
1483
|
// Only expose enabled and cacheMaxAge to client, not apiKey
|
|
1053
|
-
googleStaticMapsProxy:
|
|
1484
|
+
googleStaticMapsProxy: googleMapsEnabled ? { enabled: true, cacheMaxAge: config.googleStaticMapsProxy?.cacheMaxAge ?? 3600 } : void 0
|
|
1054
1485
|
};
|
|
1055
|
-
if (config.registry) {
|
|
1056
|
-
nuxt.options.runtimeConfig.public = nuxt.options.runtimeConfig.public || {};
|
|
1057
|
-
nuxt.options.runtimeConfig.public.scripts = defu(
|
|
1058
|
-
nuxt.options.runtimeConfig.public.scripts || {},
|
|
1059
|
-
config.registry
|
|
1060
|
-
);
|
|
1061
|
-
}
|
|
1062
1486
|
if (config.defaultScriptOptions?.bundle !== void 0) {
|
|
1063
1487
|
logger.warn(
|
|
1064
1488
|
"`scripts.defaultScriptOptions.bundle` is deprecated. Use `scripts.firstParty: true` instead. First-party mode is now enabled by default."
|
|
1065
1489
|
);
|
|
1066
1490
|
}
|
|
1067
|
-
const
|
|
1068
|
-
const
|
|
1069
|
-
const isStaticPreset = staticPresets.includes(preset);
|
|
1070
|
-
const firstPartyEnabled = !!config.firstParty;
|
|
1071
|
-
const firstPartyPrefix = typeof config.firstParty === "object" ? config.firstParty.prefix : void 0;
|
|
1072
|
-
const firstPartyCollectPrefix = typeof config.firstParty === "object" ? config.firstParty.collectPrefix || "/_proxy" : "/_proxy";
|
|
1073
|
-
const firstPartyPrivacy = typeof config.firstParty === "object" ? config.firstParty.privacy : void 0;
|
|
1074
|
-
const assetsPrefix = firstPartyPrefix || config.assets?.prefix || "/_scripts";
|
|
1491
|
+
const firstParty = await setupFirstParty(config, resolvePath);
|
|
1492
|
+
const assetsPrefix = firstParty.assetsPrefix;
|
|
1075
1493
|
if (config.partytown?.length) {
|
|
1076
1494
|
config.registry = config.registry || {};
|
|
1077
1495
|
const requiredForwards = [];
|
|
@@ -1084,12 +1502,8 @@ const module$1 = defineNuxtModule({
|
|
|
1084
1502
|
}
|
|
1085
1503
|
const reg = config.registry;
|
|
1086
1504
|
const existing = reg[scriptKey];
|
|
1087
|
-
if (
|
|
1505
|
+
if (existing) {
|
|
1088
1506
|
existing[1] = { ...existing[1], partytown: true };
|
|
1089
|
-
} else if (existing && typeof existing === "object" && existing !== true && existing !== "mock") {
|
|
1090
|
-
reg[scriptKey] = [existing, { partytown: true }];
|
|
1091
|
-
} else if (existing === true || existing === "mock") {
|
|
1092
|
-
reg[scriptKey] = [{}, { partytown: true }];
|
|
1093
1507
|
} else {
|
|
1094
1508
|
reg[scriptKey] = [{}, { partytown: true }];
|
|
1095
1509
|
}
|
|
@@ -1123,110 +1537,14 @@ const module$1 = defineNuxtModule({
|
|
|
1123
1537
|
path: await resolvePath("./runtime/components"),
|
|
1124
1538
|
pathPrefix: false
|
|
1125
1539
|
});
|
|
1540
|
+
fixSelfClosingScriptComponents(nuxt);
|
|
1126
1541
|
addTemplate({
|
|
1127
1542
|
filename: "nuxt-scripts-trigger-resolver.mjs",
|
|
1128
1543
|
getContents() {
|
|
1129
1544
|
return templateTriggerResolver(config.defaultScriptOptions);
|
|
1130
1545
|
}
|
|
1131
1546
|
});
|
|
1132
|
-
|
|
1133
|
-
logger.debug("[nuxt-scripts] First-party config:", { firstPartyEnabled, firstPartyPrivacy, firstPartyCollectPrefix });
|
|
1134
|
-
if (firstPartyEnabled && !nuxt.options.dev) {
|
|
1135
|
-
const swPath = "/_nuxt-scripts-sw.js";
|
|
1136
|
-
const swRules = getSWInterceptRules(firstPartyCollectPrefix);
|
|
1137
|
-
addServerHandler({
|
|
1138
|
-
route: swPath,
|
|
1139
|
-
handler: swHandlerPath
|
|
1140
|
-
});
|
|
1141
|
-
addPluginTemplate({
|
|
1142
|
-
filename: "nuxt-scripts-sw-register.client.mjs",
|
|
1143
|
-
getContents() {
|
|
1144
|
-
return `import { defineNuxtPlugin } from 'nuxt/app'
|
|
1145
|
-
|
|
1146
|
-
export default defineNuxtPlugin({
|
|
1147
|
-
name: 'nuxt-scripts:sw-register',
|
|
1148
|
-
enforce: 'pre',
|
|
1149
|
-
async setup() {
|
|
1150
|
-
if (!('serviceWorker' in navigator)) return;
|
|
1151
|
-
|
|
1152
|
-
try {
|
|
1153
|
-
const reg = await navigator.serviceWorker.register('${swPath}', { scope: '/' });
|
|
1154
|
-
|
|
1155
|
-
// Wait for SW to be active and controlling this page
|
|
1156
|
-
if (!navigator.serviceWorker.controller) {
|
|
1157
|
-
await new Promise((resolve) => {
|
|
1158
|
-
const onControllerChange = () => {
|
|
1159
|
-
navigator.serviceWorker.removeEventListener('controllerchange', onControllerChange);
|
|
1160
|
-
resolve();
|
|
1161
|
-
};
|
|
1162
|
-
navigator.serviceWorker.addEventListener('controllerchange', onControllerChange);
|
|
1163
|
-
|
|
1164
|
-
// Fallback timeout
|
|
1165
|
-
setTimeout(resolve, 2000);
|
|
1166
|
-
});
|
|
1167
|
-
}
|
|
1168
|
-
} catch (err) {
|
|
1169
|
-
console.warn('[nuxt-scripts] SW registration failed:', err);
|
|
1170
|
-
}
|
|
1171
|
-
},
|
|
1172
|
-
})
|
|
1173
|
-
`;
|
|
1174
|
-
}
|
|
1175
|
-
});
|
|
1176
|
-
addPluginTemplate({
|
|
1177
|
-
filename: "nuxt-scripts-beacon-intercept.client.mjs",
|
|
1178
|
-
getContents() {
|
|
1179
|
-
const rulesJson = JSON.stringify(swRules);
|
|
1180
|
-
return `export default defineNuxtPlugin({
|
|
1181
|
-
name: 'nuxt-scripts:beacon-intercept',
|
|
1182
|
-
enforce: 'pre',
|
|
1183
|
-
setup() {
|
|
1184
|
-
if (typeof navigator === 'undefined' || !navigator.sendBeacon) return;
|
|
1185
|
-
|
|
1186
|
-
const rules = ${rulesJson};
|
|
1187
|
-
const originalBeacon = navigator.sendBeacon.bind(navigator);
|
|
1188
|
-
|
|
1189
|
-
navigator.sendBeacon = (url, data) => {
|
|
1190
|
-
try {
|
|
1191
|
-
const parsed = new URL(url, window.location.origin);
|
|
1192
|
-
|
|
1193
|
-
// Check if this URL matches any of our proxy rules
|
|
1194
|
-
for (const rule of rules) {
|
|
1195
|
-
if (parsed.hostname === rule.pattern || parsed.hostname.endsWith('.' + rule.pattern)) {
|
|
1196
|
-
// Check path prefix if specified
|
|
1197
|
-
if (rule.pathPrefix && !parsed.pathname.startsWith(rule.pathPrefix)) {
|
|
1198
|
-
continue;
|
|
1199
|
-
}
|
|
1200
|
-
|
|
1201
|
-
// Rewrite to proxy: strip pathPrefix from original, prepend target
|
|
1202
|
-
const pathWithoutPrefix = rule.pathPrefix
|
|
1203
|
-
? parsed.pathname.slice(rule.pathPrefix.length)
|
|
1204
|
-
: parsed.pathname;
|
|
1205
|
-
const separator = pathWithoutPrefix.startsWith('/') ? '' : '/';
|
|
1206
|
-
const proxyUrl = rule.target + separator + pathWithoutPrefix + parsed.search;
|
|
1207
|
-
|
|
1208
|
-
return originalBeacon(proxyUrl, data);
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1211
|
-
} catch (e) {
|
|
1212
|
-
// URL parsing failed, pass through
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
return originalBeacon(url, data);
|
|
1216
|
-
};
|
|
1217
|
-
},
|
|
1218
|
-
})
|
|
1219
|
-
`;
|
|
1220
|
-
}
|
|
1221
|
-
});
|
|
1222
|
-
nuxt.options.runtimeConfig.public["nuxt-scripts-sw"] = { path: swPath };
|
|
1223
|
-
const proxyHandlerPath = await resolvePath("./runtime/server/proxy-handler");
|
|
1224
|
-
logger.debug("[nuxt-scripts] Registering proxy handler:", `${firstPartyCollectPrefix}/**`, "->", proxyHandlerPath);
|
|
1225
|
-
addServerHandler({
|
|
1226
|
-
route: `${firstPartyCollectPrefix}/**`,
|
|
1227
|
-
handler: proxyHandlerPath
|
|
1228
|
-
});
|
|
1229
|
-
}
|
|
1547
|
+
logger.debug("[nuxt-scripts] First-party config:", firstParty);
|
|
1230
1548
|
const scripts = await registry(resolvePath);
|
|
1231
1549
|
for (const script of scripts) {
|
|
1232
1550
|
if (script.import?.name) {
|
|
@@ -1254,89 +1572,26 @@ export default defineNuxtPlugin({
|
|
|
1254
1572
|
});
|
|
1255
1573
|
}
|
|
1256
1574
|
const { renderedScript } = setupPublicAssetStrategy(config.assets);
|
|
1257
|
-
if (
|
|
1258
|
-
const
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
if (proxyKey) {
|
|
1267
|
-
const proxyConfig = proxyConfigs[proxyKey];
|
|
1268
|
-
if (proxyConfig?.routes) {
|
|
1269
|
-
Object.assign(neededRoutes, proxyConfig.routes);
|
|
1270
|
-
for (const routePath of Object.keys(proxyConfig.routes)) {
|
|
1271
|
-
routePrivacyOverrides[routePath] = proxyConfig.privacy;
|
|
1272
|
-
}
|
|
1273
|
-
} else {
|
|
1274
|
-
unsupportedScripts.push(key);
|
|
1275
|
-
}
|
|
1276
|
-
}
|
|
1277
|
-
}
|
|
1278
|
-
if (config.registry?.posthog && typeof config.registry.posthog === "object") {
|
|
1279
|
-
const phConfig = config.registry.posthog;
|
|
1280
|
-
if (!phConfig.apiHost) {
|
|
1281
|
-
const region = phConfig.region || "us";
|
|
1282
|
-
phConfig.apiHost = region === "eu" ? `${firstPartyCollectPrefix}/ph-eu` : `${firstPartyCollectPrefix}/ph`;
|
|
1283
|
-
}
|
|
1284
|
-
}
|
|
1285
|
-
if (unsupportedScripts.length && nuxt.options.dev) {
|
|
1286
|
-
logger.warn(
|
|
1287
|
-
`First-party mode is enabled but these scripts don't support it yet: ${unsupportedScripts.join(", ")}.
|
|
1288
|
-
They will load directly from third-party servers. Request support at https://github.com/nuxt/scripts/issues`
|
|
1289
|
-
);
|
|
1290
|
-
}
|
|
1291
|
-
const flatRoutes = {};
|
|
1292
|
-
for (const [path, config2] of Object.entries(neededRoutes)) {
|
|
1293
|
-
flatRoutes[path] = config2.proxy;
|
|
1294
|
-
}
|
|
1295
|
-
const allRewrites = [];
|
|
1296
|
-
for (const key of registryKeys) {
|
|
1297
|
-
const script = registryScriptsWithImport.find((s) => s.import.name.toLowerCase() === `usescript${key.toLowerCase()}`);
|
|
1298
|
-
const proxyKey = script?.proxy !== false ? script?.proxy || key : void 0;
|
|
1299
|
-
if (proxyKey) {
|
|
1300
|
-
const proxyConfig = proxyConfigs[proxyKey];
|
|
1301
|
-
if (proxyConfig?.rewrite) {
|
|
1302
|
-
allRewrites.push(...proxyConfig.rewrite);
|
|
1303
|
-
}
|
|
1304
|
-
}
|
|
1575
|
+
if (firstParty.enabled) {
|
|
1576
|
+
const { proxyPrefix, devtools: devtoolsData } = finalizeFirstParty({
|
|
1577
|
+
firstParty,
|
|
1578
|
+
registry: config.registry,
|
|
1579
|
+
registryScripts,
|
|
1580
|
+
nuxtOptions: nuxt.options
|
|
1581
|
+
});
|
|
1582
|
+
if (devtoolsData) {
|
|
1583
|
+
nuxt.options.runtimeConfig.public["nuxt-scripts-devtools"] = devtoolsData;
|
|
1305
1584
|
}
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
if (Object.keys(neededRoutes).length) {
|
|
1315
|
-
if (nuxt.options.dev) {
|
|
1316
|
-
const routeCount = Object.keys(neededRoutes).length;
|
|
1317
|
-
const scriptsCount = registryKeys.length;
|
|
1318
|
-
const privacyLabel = firstPartyPrivacy === void 0 ? "per-script" : typeof firstPartyPrivacy === "boolean" ? firstPartyPrivacy ? "anonymize" : "passthrough" : "custom";
|
|
1319
|
-
logger.success(`First-party mode enabled for ${scriptsCount} script(s), ${routeCount} proxy route(s) configured (privacy: ${privacyLabel})`);
|
|
1320
|
-
if (logger.level >= 4) {
|
|
1321
|
-
for (const [path, config2] of Object.entries(neededRoutes)) {
|
|
1322
|
-
logger.debug(` ${path} \u2192 ${config2.proxy}`);
|
|
1323
|
-
}
|
|
1324
|
-
}
|
|
1585
|
+
if (config.partytown?.length && hasNuxtModule("@nuxtjs/partytown")) {
|
|
1586
|
+
const partytownConfig = nuxt.options.partytown || {};
|
|
1587
|
+
if (!partytownConfig.resolveUrl) {
|
|
1588
|
+
partytownConfig.resolveUrl = generatePartytownResolveUrl(proxyPrefix);
|
|
1589
|
+
nuxt.options.partytown = partytownConfig;
|
|
1590
|
+
logger.info("[partytown] Auto-configured resolveUrl for first-party proxy");
|
|
1591
|
+
} else {
|
|
1592
|
+
logger.warn("[partytown] Custom resolveUrl already set \u2014 first-party proxy URLs will not be auto-rewritten in Partytown worker. Add first-party proxy rules to your resolveUrl manually.");
|
|
1325
1593
|
}
|
|
1326
1594
|
}
|
|
1327
|
-
if (isStaticPreset) {
|
|
1328
|
-
logger.warn(
|
|
1329
|
-
`First-party collection endpoints require a server runtime (detected: ${preset || "static"}).
|
|
1330
|
-
Scripts will be bundled, but collection requests will not be proxied.
|
|
1331
|
-
|
|
1332
|
-
Options:
|
|
1333
|
-
1. Configure platform rewrites (Vercel, Netlify, Cloudflare)
|
|
1334
|
-
2. Switch to server-rendered mode (ssr: true)
|
|
1335
|
-
3. Disable with firstParty: false
|
|
1336
|
-
|
|
1337
|
-
See: https://scripts.nuxt.com/docs/guides/first-party#static-hosting`
|
|
1338
|
-
);
|
|
1339
|
-
}
|
|
1340
1595
|
}
|
|
1341
1596
|
const moduleInstallPromises = /* @__PURE__ */ new Map();
|
|
1342
1597
|
addBuildPlugin(NuxtScriptsCheckScripts(), {
|
|
@@ -1345,9 +1600,10 @@ See: https://scripts.nuxt.com/docs/guides/first-party#static-hosting`
|
|
|
1345
1600
|
addBuildPlugin(NuxtScriptBundleTransformer({
|
|
1346
1601
|
scripts: registryScriptsWithImport,
|
|
1347
1602
|
registryConfig: nuxt.options.runtimeConfig.public.scripts,
|
|
1348
|
-
defaultBundle:
|
|
1349
|
-
|
|
1350
|
-
|
|
1603
|
+
defaultBundle: firstParty.enabled || config.defaultScriptOptions?.bundle,
|
|
1604
|
+
proxyConfigs: firstParty.proxyConfigs,
|
|
1605
|
+
proxyPrefix: firstParty.proxyPrefix,
|
|
1606
|
+
partytownScripts: new Set(config.partytown || []),
|
|
1351
1607
|
moduleDetected(module) {
|
|
1352
1608
|
if (nuxt.options.dev && module !== "@nuxt/scripts" && !moduleInstallPromises.has(module) && !hasNuxtModule(module))
|
|
1353
1609
|
moduleInstallPromises.set(module, () => installNuxtModule(module));
|
|
@@ -1360,37 +1616,44 @@ See: https://scripts.nuxt.com/docs/guides/first-party#static-hosting`
|
|
|
1360
1616
|
renderedScript
|
|
1361
1617
|
}));
|
|
1362
1618
|
nuxt.hooks.hook("build:done", async () => {
|
|
1363
|
-
const initPromise =
|
|
1619
|
+
const initPromise = [...moduleInstallPromises.values()];
|
|
1364
1620
|
for (const p of initPromise)
|
|
1365
1621
|
await p?.();
|
|
1366
1622
|
});
|
|
1367
1623
|
});
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1624
|
+
const enabledEndpoints = {};
|
|
1625
|
+
for (const script of scripts) {
|
|
1626
|
+
if (!script.serverHandlers?.length || !script.registryKey)
|
|
1627
|
+
continue;
|
|
1628
|
+
const isEnabled = script.registryKey === "googleMaps" ? config.googleStaticMapsProxy?.enabled || config.registry?.googleMaps : config.registry?.[script.registryKey];
|
|
1629
|
+
if (!isEnabled)
|
|
1630
|
+
continue;
|
|
1631
|
+
enabledEndpoints[script.registryKey] = true;
|
|
1632
|
+
for (const handler of script.serverHandlers) {
|
|
1633
|
+
addServerHandler({
|
|
1634
|
+
route: handler.route,
|
|
1635
|
+
handler: handler.handler,
|
|
1636
|
+
middleware: handler.middleware
|
|
1637
|
+
});
|
|
1638
|
+
}
|
|
1639
|
+
if (script.registryKey === "gravatar") {
|
|
1640
|
+
const gravatarConfig = config.registry?.gravatar?.[0] || {};
|
|
1641
|
+
nuxt.options.runtimeConfig.public["nuxt-scripts"] = defu(
|
|
1642
|
+
{ gravatarProxy: { cacheMaxAge: gravatarConfig.cacheMaxAge ?? 3600 } },
|
|
1643
|
+
nuxt.options.runtimeConfig.public["nuxt-scripts"]
|
|
1644
|
+
);
|
|
1645
|
+
}
|
|
1646
|
+
if (script.registryKey === "googleMaps") {
|
|
1647
|
+
nuxt.options.runtimeConfig["nuxt-scripts"] = defu(
|
|
1648
|
+
{ googleMapsGeocodeProxy: { apiKey: nuxt.options.runtimeConfig.public.scripts?.googleMaps?.apiKey } },
|
|
1649
|
+
nuxt.options.runtimeConfig["nuxt-scripts"]
|
|
1650
|
+
);
|
|
1651
|
+
}
|
|
1373
1652
|
}
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
addServerHandler({
|
|
1379
|
-
route: "/api/_scripts/x-embed-image",
|
|
1380
|
-
handler: await resolvePath("./runtime/server/x-embed-image")
|
|
1381
|
-
});
|
|
1382
|
-
addServerHandler({
|
|
1383
|
-
route: "/api/_scripts/instagram-embed",
|
|
1384
|
-
handler: await resolvePath("./runtime/server/instagram-embed")
|
|
1385
|
-
});
|
|
1386
|
-
addServerHandler({
|
|
1387
|
-
route: "/api/_scripts/instagram-embed-image",
|
|
1388
|
-
handler: await resolvePath("./runtime/server/instagram-embed-image")
|
|
1389
|
-
});
|
|
1390
|
-
addServerHandler({
|
|
1391
|
-
route: "/api/_scripts/instagram-embed-asset",
|
|
1392
|
-
handler: await resolvePath("./runtime/server/instagram-embed-asset")
|
|
1393
|
-
});
|
|
1653
|
+
nuxt.options.runtimeConfig.public["nuxt-scripts"] = defu(
|
|
1654
|
+
{ endpoints: enabledEndpoints },
|
|
1655
|
+
nuxt.options.runtimeConfig.public["nuxt-scripts"]
|
|
1656
|
+
);
|
|
1394
1657
|
if (nuxt.options.dev) {
|
|
1395
1658
|
setupDevToolsUI(config, resolvePath);
|
|
1396
1659
|
}
|