@nuxt/scripts 1.0.0-beta.7 → 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/devtools-client/200.html +1 -0
- package/dist/devtools-client/404.html +1 -0
- package/dist/devtools-client/_fonts/4ppnHhMi-pBsWSPo7mY0avYxlDoAg1N3PTzCwXLZ5rA-d9oibkGnTd1JL3tc_xnaVgBLYmOB8kjrK2cvZaqwj9s.woff2 +0 -0
- package/dist/devtools-client/_fonts/4qBuU9MRVUlPZNPSF7Xom_sK8RBEnfYu-9VXFrdq8A8-8TDwLE1HAj1sQn7XxVWtM_7sIaPM-DTdO3Pf8U2DF1U.woff2 +0 -0
- package/dist/devtools-client/_fonts/6dYsbWUd_BpKJ7mdDihgOcya1gHXLpJBuMYXux3WMjE-q3fYNS8YbW5n7ZeXI2vSNgkRWW5VDPKAl51SNTjG2qk.woff2 +0 -0
- package/dist/devtools-client/_fonts/Lr-hqqZZsYmCt0ITUlr1CUrWim9fsKvoDFZliMxgNHY-iTa_Yt_PzhOY9TX7ZXdSlEPim6iRt92xhECwaxWxd5w.woff2 +0 -0
- package/dist/devtools-client/_fonts/OknHvWI6KtYn1JQBzX7eSpNDBQ8520F9TvSUJYkVf6A-xeZn9253svK_8Q2LD0XEruY_MnEsuCRO5LenPoggC0Y.woff2 +0 -0
- package/dist/devtools-client/_fonts/PV2hrQG6wq5BlIPDjdL1IcOflycaghyt5MHzlBqZtlo-lb_WexLz3VZqfTN0oi554iBH5tT2j2UFEV-XErCAS3E.woff2 +0 -0
- package/dist/devtools-client/_fonts/UA7OtwYHwGN_HjcVGTdmiQxUit7FlqkCwxVUWSeXVnQ-B4OXCFOL_tWrYODpQTc07aMaj0c2cewTOmBRWR9tD-A.woff2 +0 -0
- package/dist/devtools-client/_fonts/VE4cDVCv5MxbFM7ZLoLCGbIpNd71zhp7MDI9lmN5Y7I-xZyDYCUVrd6LV8eVGF3Um3UZjBFuUtDGtvdyTBBRYBo.woff2 +0 -0
- package/dist/devtools-client/_fonts/fVoGbnMbBFd5L9BBp9fUPavUSkZ_EmsQNSyadkT-108-U4T0khaeLQSIhtt9eVvaCEKJjtWJ4ioRJOf8hvqkWY0.woff2 +0 -0
- package/dist/devtools-client/_fonts/lQAxeCEs1R0Lw-H9XRU1RlOARQN8J6npRsPjyEDMe5s-_DUSLEkO3tKTuun_gSnDLoQPVEnpOnyqZMOw0ByZ6PA.woff2 +0 -0
- package/dist/devtools-client/_fonts/lntlqNHKLV2n82yTwMde70QqOjcfLE2XJ5oKZ3vRPWc-z6TxpIZQdWXztWLr9_OFWqt_WJJoeGtuK_-XQMZGQwE.woff2 +0 -0
- package/dist/devtools-client/_fonts/qxAYvKsXWeYv731eb-h5TRurcdIP_W44mpNdX-HABAk-zUDeMEFlNtNbrwvT9JxLEBg0TphGy70O6RfIoIX_ZwU.woff2 +0 -0
- package/dist/devtools-client/_nuxt/B3kN3DAy.js +1 -0
- package/dist/devtools-client/_nuxt/B8PEiB0p.js +1 -0
- package/dist/devtools-client/_nuxt/C8jhSQ8l.js +1 -0
- package/dist/devtools-client/_nuxt/CJD6wrkT.js +188 -0
- package/dist/devtools-client/_nuxt/CfOsp0mU.js +1 -0
- package/dist/devtools-client/_nuxt/DKL6PHO3.js +1 -0
- package/dist/devtools-client/_nuxt/ajngqPCs.js +1 -0
- package/dist/devtools-client/_nuxt/builds/latest.json +1 -0
- package/dist/devtools-client/_nuxt/builds/meta/b800a0be-5cab-4ea6-89e3-dd3a85690a73.json +1 -0
- package/dist/devtools-client/_nuxt/dlaR8P-P.js +1 -0
- package/dist/devtools-client/_nuxt/entry.BwpOBArY.css +1 -0
- package/dist/devtools-client/_nuxt/error-404.CvOVjXeC.css +1 -0
- package/dist/devtools-client/_nuxt/error-500.BIm53nmx.css +1 -0
- package/dist/devtools-client/_nuxt/first-party.C8Ha4JLM.css +1 -0
- package/dist/devtools-client/_nuxt/index.CA-OpSj0.css +1 -0
- package/dist/devtools-client/_nuxt/registry.B9lnjF_b.css +1 -0
- package/dist/devtools-client/_nuxt/wDzz0qaB.js +1 -0
- package/dist/devtools-client/docs/index.html +1 -0
- package/dist/devtools-client/first-party/index.html +1 -0
- package/dist/devtools-client/index.html +1 -0
- package/dist/devtools-client/registry/index.html +1 -0
- package/dist/module.d.mts +29 -84
- package/dist/module.d.ts +121 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +939 -755
- package/dist/registry.d.mts +91 -4
- package/dist/registry.d.ts +93 -0
- package/dist/registry.mjs +668 -326
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.d.vue.ts +15 -79
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue +78 -180
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue.d.ts +15 -79
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.d.vue.ts +6 -55
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.vue +12 -83
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.vue.d.ts +6 -55
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsCircle.d.vue.ts +5 -1
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsCircle.vue +24 -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 +60 -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 +56 -57
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.vue.d.ts +9 -5
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.d.vue.ts +24 -41
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue +69 -73
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue.d.ts +24 -41
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.d.vue.ts +36 -4
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue +82 -37
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue.d.ts +36 -4
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.d.vue.ts +78 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.vue +222 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.vue.d.ts +78 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.d.vue.ts +10 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.vue +9 -41
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.vue.d.ts +10 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolygon.d.vue.ts +7 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolygon.vue +23 -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 +23 -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 +24 -38
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsRectangle.vue.d.ts +7 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsStaticMap.d.vue.ts +200 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsStaticMap.vue +165 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsStaticMap.vue.d.ts +200 -0
- 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 +10 -0
- package/dist/runtime/components/GoogleMaps/injectionKeys.js +2 -0
- package/dist/runtime/components/GoogleMaps/useGoogleMapsResource.d.ts +48 -0
- package/dist/runtime/components/GoogleMaps/useGoogleMapsResource.js +51 -0
- package/dist/runtime/components/ScriptBlueskyEmbed.d.vue.ts +85 -0
- package/dist/runtime/components/ScriptBlueskyEmbed.vue +88 -0
- package/dist/runtime/components/ScriptBlueskyEmbed.vue.d.ts +85 -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 +1 -2
- package/dist/runtime/components/ScriptInstagramEmbed.vue +8 -3
- package/dist/runtime/components/ScriptInstagramEmbed.vue.d.ts +1 -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 +0 -2
- package/dist/runtime/components/ScriptXEmbed.vue +14 -8
- package/dist/runtime/components/ScriptXEmbed.vue.d.ts +0 -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 +148 -8
- 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/devtools-standalone-bridge.client.d.ts +8 -0
- package/dist/runtime/devtools-standalone-bridge.client.js +50 -0
- 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 +3 -25
- 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 +36 -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 +5 -13
- 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 +19 -14
- package/dist/runtime/registry/posthog.d.ts +10 -12
- package/dist/runtime/registry/posthog.js +3 -12
- 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 +5 -34
- 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/bluesky-embed-image.d.ts +2 -0
- 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 +176 -35
- package/dist/runtime/server/proxy-handler.js +101 -83
- 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 -10
- package/dist/runtime/server/utils/privacy.js +60 -40
- 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 +272 -51
- package/dist/runtime/types.js +0 -2
- package/dist/runtime/utils/pure.d.ts +1 -1
- package/dist/runtime/utils.d.ts +6 -4
- package/dist/runtime/utils.js +31 -14
- package/dist/stats.d.mts +202 -0
- package/dist/stats.d.ts +202 -0
- package/dist/stats.mjs +3875 -0
- package/dist/types-source.d.mts +17 -0
- package/dist/types-source.d.ts +17 -0
- package/dist/types-source.mjs +3414 -0
- package/dist/types.d.mts +4 -2
- package/package.json +35 -61
- package/README.md +0 -86
- package/dist/client/200.html +0 -1
- package/dist/client/404.html +0 -1
- package/dist/client/_nuxt/BJa0m50V.js +0 -1
- package/dist/client/_nuxt/BPQ3VLAy.js +0 -1
- package/dist/client/_nuxt/Ci5iXYuB.js +0 -1
- package/dist/client/_nuxt/DaI2y8Uz.js +0 -162
- package/dist/client/_nuxt/builds/latest.json +0 -1
- package/dist/client/_nuxt/builds/meta/9b4fb16a-3c62-48b0-8295-126cb077b5d3.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/client/_nuxt/vPLZfVXe.js +0 -1
- package/dist/client/index.html +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/validation/mock.d.ts +0 -42
- package/dist/runtime/validation/mock.js +0 -21
- package/dist/runtime/validation/valibot.d.ts +0 -1
- package/dist/runtime/validation/valibot.js +0 -1
- /package/dist/{client → devtools-client}/_nuxt/CVO1_9PV.js +0 -0
- /package/dist/{client → devtools-client}/_nuxt/Cp-IABpG.js +0 -0
- /package/dist/{client → devtools-client}/_nuxt/D0r3Knsf.js +0 -0
package/dist/module.mjs
CHANGED
|
@@ -1,88 +1,45 @@
|
|
|
1
|
-
import { useNuxt, extendViteConfig, useLogger, addDevServerHandler, extendRouteRules, tryUseNuxt, logger as logger$1, addTypeTemplate, defineNuxtModule, createResolver, hasNuxtModule, addImports, addComponentsDir, addTemplate, addPluginTemplate, addServerHandler, addBuildPlugin } from '@nuxt/kit';
|
|
2
1
|
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
3
|
-
import {
|
|
2
|
+
import { useNuxt, addDevServerHandler, extendRouteRules, tryUseNuxt, createResolver, extendViteConfig, logger as logger$1, useLogger, addTypeTemplate, defineNuxtModule, addPluginTemplate, addServerHandler, addImports, addComponentsDir, addTemplate, hasNuxtModule, addBuildPlugin } from '@nuxt/kit';
|
|
4
3
|
import { defu } from 'defu';
|
|
4
|
+
import { join, resolve } from 'pathe';
|
|
5
5
|
import { resolvePackageJSON, readPackageJSON } from 'pkg-types';
|
|
6
|
-
import { addCustomTab } from '@nuxt/devtools-kit';
|
|
7
|
-
import { createHash } from 'node:crypto';
|
|
8
|
-
import fsp from 'node:fs/promises';
|
|
9
|
-
import { createUnplugin } from 'unplugin';
|
|
10
|
-
import MagicString from 'magic-string';
|
|
11
|
-
import { parseAndWalk } from 'oxc-walker';
|
|
12
|
-
import { joinURL, parseURL, parseQuery, hasProtocol } from 'ufo';
|
|
13
|
-
import { hash } from 'ohash';
|
|
14
|
-
import { colors } from 'consola/utils';
|
|
15
|
-
import { fetch, $fetch } from 'ofetch';
|
|
16
6
|
import { lazyEventHandler, eventHandler, createError } from 'h3';
|
|
7
|
+
import { fetch, $fetch } from 'ofetch';
|
|
8
|
+
import { joinURL, parseURL, parseQuery, hasProtocol } from 'ufo';
|
|
17
9
|
import { createStorage } from 'unstorage';
|
|
18
10
|
import fsDriver from 'unstorage/drivers/fs-lite';
|
|
19
|
-
import { pathToFileURL } from 'node:url';
|
|
20
11
|
import { isCI, provider } from 'std-env';
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const sirv = await import('sirv').then((r) => r.default || r);
|
|
32
|
-
server.middlewares.use(
|
|
33
|
-
DEVTOOLS_UI_ROUTE,
|
|
34
|
-
sirv(clientPath, { dev: true, single: true })
|
|
35
|
-
);
|
|
36
|
-
});
|
|
37
|
-
} else {
|
|
38
|
-
extendViteConfig((config) => {
|
|
39
|
-
config.server = config.server || {};
|
|
40
|
-
config.server.proxy = config.server.proxy || {};
|
|
41
|
-
config.server.proxy[DEVTOOLS_UI_ROUTE] = {
|
|
42
|
-
target: `http://localhost:${DEVTOOLS_UI_LOCAL_PORT}${DEVTOOLS_UI_ROUTE}`,
|
|
43
|
-
changeOrigin: true,
|
|
44
|
-
followRedirects: true,
|
|
45
|
-
rewrite: (path) => path.replace(DEVTOOLS_UI_ROUTE, "")
|
|
46
|
-
};
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
addCustomTab({
|
|
50
|
-
// unique identifier
|
|
51
|
-
name: "nuxt-scripts",
|
|
52
|
-
// title to display in the tab
|
|
53
|
-
title: "Scripts",
|
|
54
|
-
// any icon from Iconify, or a URL to an image
|
|
55
|
-
icon: "carbon:script",
|
|
56
|
-
// iframe view
|
|
57
|
-
view: {
|
|
58
|
-
type: "iframe",
|
|
59
|
-
src: DEVTOOLS_UI_ROUTE
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const logger = useLogger("@nuxt/scripts");
|
|
12
|
+
import { parseAndWalk, ScopeTracker, walk, ScopeTrackerFunction, ScopeTrackerIdentifier, ScopeTrackerFunctionParam, ScopeTrackerVariable } from 'oxc-walker';
|
|
13
|
+
import { createUnplugin } from 'unplugin';
|
|
14
|
+
import { pathToFileURL } from 'node:url';
|
|
15
|
+
import { createHash } from 'node:crypto';
|
|
16
|
+
import fsp from 'node:fs/promises';
|
|
17
|
+
import { colors } from 'consola/utils';
|
|
18
|
+
import MagicString from 'magic-string';
|
|
19
|
+
import { hash } from 'ohash';
|
|
20
|
+
import { getBundleResolve, registry, resolveCapabilities, getPartytownForwards, buildProxyConfigsFromRegistry, generatePartytownResolveUrl } from './registry.mjs';
|
|
21
|
+
import '../dist/runtime/registry/schemas.js';
|
|
65
22
|
|
|
66
23
|
const renderedScript = /* @__PURE__ */ new Map();
|
|
67
24
|
const ONE_YEAR_IN_SECONDS = 60 * 60 * 24 * 365;
|
|
68
|
-
|
|
25
|
+
function bundleStorage() {
|
|
69
26
|
const nuxt = tryUseNuxt();
|
|
70
27
|
return createStorage({
|
|
71
28
|
driver: fsDriver({
|
|
72
29
|
base: resolve(nuxt?.options.rootDir || "", "node_modules/.cache/nuxt/scripts")
|
|
73
30
|
})
|
|
74
31
|
});
|
|
75
|
-
}
|
|
76
|
-
function setupPublicAssetStrategy(
|
|
77
|
-
const assetsBaseURL = options.prefix || "/_scripts";
|
|
32
|
+
}
|
|
33
|
+
function setupPublicAssetStrategy(assetsBaseURL) {
|
|
78
34
|
const nuxt = useNuxt();
|
|
79
35
|
const storage = bundleStorage();
|
|
80
36
|
addDevServerHandler({
|
|
81
37
|
route: assetsBaseURL,
|
|
82
38
|
handler: lazyEventHandler(async () => {
|
|
83
39
|
return eventHandler(async (event) => {
|
|
84
|
-
const
|
|
85
|
-
const
|
|
40
|
+
const cleanPath = (event.path || "").split("?")[0]?.slice(1) || "";
|
|
41
|
+
const filename = cleanPath;
|
|
42
|
+
const scriptDescriptor = renderedScript.get(join(assetsBaseURL, cleanPath));
|
|
86
43
|
if (!scriptDescriptor || scriptDescriptor instanceof Error)
|
|
87
44
|
throw createError({ statusCode: 404 });
|
|
88
45
|
if (scriptDescriptor.content) {
|
|
@@ -122,291 +79,258 @@ function setupPublicAssetStrategy(options = {}) {
|
|
|
122
79
|
};
|
|
123
80
|
}
|
|
124
81
|
|
|
125
|
-
|
|
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
|
-
{ from: "facebook.com/tr", to: `${collectPrefix}/meta-tr` },
|
|
178
|
-
// Additional Meta tracking domains
|
|
179
|
-
{ from: "pixel.facebook.com", to: `${collectPrefix}/meta-px` },
|
|
180
|
-
{ from: "www.facebook.com/plugins", to: `${collectPrefix}/meta-plugins` }
|
|
181
|
-
],
|
|
182
|
-
routes: {
|
|
183
|
-
[`${collectPrefix}/meta/**`]: { proxy: "https://connect.facebook.net/**" },
|
|
184
|
-
[`${collectPrefix}/meta-tr/**`]: { proxy: "https://www.facebook.com/tr/**" },
|
|
185
|
-
[`${collectPrefix}/meta-px/**`]: { proxy: "https://pixel.facebook.com/**" },
|
|
186
|
-
[`${collectPrefix}/meta-plugins/**`]: { proxy: "https://www.facebook.com/plugins/**" }
|
|
187
|
-
}
|
|
188
|
-
},
|
|
189
|
-
tiktokPixel: {
|
|
190
|
-
// TikTok: untrusted ad network — full anonymization
|
|
191
|
-
privacy: { ip: true, userAgent: true, language: true, screen: true, timezone: true, hardware: true },
|
|
192
|
-
rewrite: [
|
|
193
|
-
{ from: "analytics.tiktok.com", to: `${collectPrefix}/tiktok` }
|
|
194
|
-
],
|
|
195
|
-
routes: {
|
|
196
|
-
[`${collectPrefix}/tiktok/**`]: { proxy: "https://analytics.tiktok.com/**" }
|
|
197
|
-
}
|
|
198
|
-
},
|
|
199
|
-
segment: {
|
|
200
|
-
// Segment: trusted data pipeline — needs maximum fidelity for downstream destinations
|
|
201
|
-
privacy: { ip: false, userAgent: false, language: false, screen: false, timezone: false, hardware: false },
|
|
202
|
-
rewrite: [
|
|
203
|
-
{ from: "api.segment.io", to: `${collectPrefix}/segment` },
|
|
204
|
-
{ from: "cdn.segment.com", to: `${collectPrefix}/segment-cdn` }
|
|
205
|
-
],
|
|
206
|
-
routes: {
|
|
207
|
-
[`${collectPrefix}/segment/**`]: { proxy: "https://api.segment.io/**" },
|
|
208
|
-
[`${collectPrefix}/segment-cdn/**`]: { proxy: "https://cdn.segment.com/**" }
|
|
209
|
-
}
|
|
210
|
-
},
|
|
211
|
-
xPixel: {
|
|
212
|
-
// X/Twitter: untrusted ad network — full anonymization
|
|
213
|
-
privacy: { ip: true, userAgent: true, language: true, screen: true, timezone: true, hardware: true },
|
|
214
|
-
rewrite: [
|
|
215
|
-
{ from: "analytics.twitter.com", to: `${collectPrefix}/x` },
|
|
216
|
-
{ from: "t.co", to: `${collectPrefix}/x-t` }
|
|
217
|
-
],
|
|
218
|
-
routes: {
|
|
219
|
-
[`${collectPrefix}/x/**`]: { proxy: "https://analytics.twitter.com/**" },
|
|
220
|
-
[`${collectPrefix}/x-t/**`]: { proxy: "https://t.co/**" }
|
|
221
|
-
}
|
|
222
|
-
},
|
|
223
|
-
snapchatPixel: {
|
|
224
|
-
// Snapchat: untrusted ad network — full anonymization
|
|
225
|
-
privacy: { ip: true, userAgent: true, language: true, screen: true, timezone: true, hardware: true },
|
|
226
|
-
rewrite: [
|
|
227
|
-
{ from: "tr.snapchat.com", to: `${collectPrefix}/snap` }
|
|
228
|
-
],
|
|
229
|
-
routes: {
|
|
230
|
-
[`${collectPrefix}/snap/**`]: { proxy: "https://tr.snapchat.com/**" }
|
|
231
|
-
}
|
|
232
|
-
},
|
|
233
|
-
redditPixel: {
|
|
234
|
-
// Reddit: untrusted ad network — full anonymization
|
|
235
|
-
privacy: { ip: true, userAgent: true, language: true, screen: true, timezone: true, hardware: true },
|
|
236
|
-
rewrite: [
|
|
237
|
-
{ from: "alb.reddit.com", to: `${collectPrefix}/reddit` },
|
|
238
|
-
{ from: "pixel-config.reddit.com", to: `${collectPrefix}/reddit-cfg` }
|
|
239
|
-
],
|
|
240
|
-
routes: {
|
|
241
|
-
[`${collectPrefix}/reddit/**`]: { proxy: "https://alb.reddit.com/**" },
|
|
242
|
-
[`${collectPrefix}/reddit-cfg/**`]: { proxy: "https://pixel-config.reddit.com/**" }
|
|
243
|
-
}
|
|
244
|
-
},
|
|
245
|
-
clarity: {
|
|
246
|
-
// Clarity: screen/UA/timezone needed for heatmaps and device filtering; rest anonymized
|
|
247
|
-
privacy: { ip: true, userAgent: false, language: true, screen: false, timezone: false, hardware: true },
|
|
248
|
-
rewrite: [
|
|
249
|
-
// Main clarity domain
|
|
250
|
-
{ from: "www.clarity.ms", to: `${collectPrefix}/clarity` },
|
|
251
|
-
// Script loader (the actual SDK is loaded from here)
|
|
252
|
-
{ from: "scripts.clarity.ms", to: `${collectPrefix}/clarity-scripts` },
|
|
253
|
-
// Data collection endpoint
|
|
254
|
-
{ from: "d.clarity.ms", to: `${collectPrefix}/clarity-data` },
|
|
255
|
-
// Event collection endpoint
|
|
256
|
-
{ from: "e.clarity.ms", to: `${collectPrefix}/clarity-events` }
|
|
257
|
-
],
|
|
258
|
-
routes: {
|
|
259
|
-
[`${collectPrefix}/clarity/**`]: { proxy: "https://www.clarity.ms/**" },
|
|
260
|
-
[`${collectPrefix}/clarity-scripts/**`]: { proxy: "https://scripts.clarity.ms/**" },
|
|
261
|
-
[`${collectPrefix}/clarity-data/**`]: { proxy: "https://d.clarity.ms/**" },
|
|
262
|
-
[`${collectPrefix}/clarity-events/**`]: { proxy: "https://e.clarity.ms/**" }
|
|
263
|
-
}
|
|
264
|
-
},
|
|
265
|
-
posthog: {
|
|
266
|
-
// No rewrites needed - PostHog uses NPM mode, SDK URLs are set via api_host config
|
|
267
|
-
// PostHog: needs real IP for GeoIP enrichment + feature flag targeting
|
|
268
|
-
privacy: { ip: false, userAgent: false, language: false, screen: false, timezone: false, hardware: false },
|
|
269
|
-
routes: {
|
|
270
|
-
// US region
|
|
271
|
-
[`${collectPrefix}/ph/static/**`]: { proxy: "https://us-assets.i.posthog.com/static/**" },
|
|
272
|
-
[`${collectPrefix}/ph/**`]: { proxy: "https://us.i.posthog.com/**" },
|
|
273
|
-
// EU region
|
|
274
|
-
[`${collectPrefix}/ph-eu/static/**`]: { proxy: "https://eu-assets.i.posthog.com/static/**" },
|
|
275
|
-
[`${collectPrefix}/ph-eu/**`]: { proxy: "https://eu.i.posthog.com/**" }
|
|
276
|
-
}
|
|
277
|
-
},
|
|
278
|
-
hotjar: {
|
|
279
|
-
// Hotjar: screen/UA/timezone needed for heatmaps and device segmentation; rest anonymized
|
|
280
|
-
privacy: { ip: true, userAgent: false, language: true, screen: false, timezone: false, hardware: true },
|
|
281
|
-
rewrite: [
|
|
282
|
-
// Static assets
|
|
283
|
-
{ from: "static.hotjar.com", to: `${collectPrefix}/hotjar` },
|
|
284
|
-
// Script loader (bootstrap script loads the main SDK from here)
|
|
285
|
-
{ from: "script.hotjar.com", to: `${collectPrefix}/hotjar-script` },
|
|
286
|
-
// Configuration/variables
|
|
287
|
-
{ from: "vars.hotjar.com", to: `${collectPrefix}/hotjar-vars` },
|
|
288
|
-
// Data ingestion endpoint
|
|
289
|
-
{ from: "in.hotjar.com", to: `${collectPrefix}/hotjar-in` },
|
|
290
|
-
// Video capture
|
|
291
|
-
{ from: "vc.hotjar.com", to: `${collectPrefix}/hotjar-vc` },
|
|
292
|
-
// Metrics/telemetry
|
|
293
|
-
{ from: "metrics.hotjar.io", to: `${collectPrefix}/hotjar-metrics` },
|
|
294
|
-
// Insights (ContentSquare integration)
|
|
295
|
-
{ from: "insights.hotjar.com", to: `${collectPrefix}/hotjar-insights` }
|
|
296
|
-
],
|
|
297
|
-
routes: {
|
|
298
|
-
[`${collectPrefix}/hotjar/**`]: { proxy: "https://static.hotjar.com/**" },
|
|
299
|
-
[`${collectPrefix}/hotjar-script/**`]: { proxy: "https://script.hotjar.com/**" },
|
|
300
|
-
[`${collectPrefix}/hotjar-vars/**`]: { proxy: "https://vars.hotjar.com/**" },
|
|
301
|
-
[`${collectPrefix}/hotjar-in/**`]: { proxy: "https://in.hotjar.com/**" },
|
|
302
|
-
[`${collectPrefix}/hotjar-vc/**`]: { proxy: "https://vc.hotjar.com/**" },
|
|
303
|
-
[`${collectPrefix}/hotjar-metrics/**`]: { proxy: "https://metrics.hotjar.io/**" },
|
|
304
|
-
[`${collectPrefix}/hotjar-insights/**`]: { proxy: "https://insights.hotjar.com/**" }
|
|
305
|
-
}
|
|
306
|
-
},
|
|
307
|
-
plausible: {
|
|
308
|
-
privacy: { ip: false, userAgent: false, language: false, screen: false, timezone: false, hardware: false },
|
|
309
|
-
rewrite: [
|
|
310
|
-
{ from: "plausible.io", to: `${collectPrefix}/plausible` }
|
|
311
|
-
],
|
|
312
|
-
routes: {
|
|
313
|
-
[`${collectPrefix}/plausible/**`]: { proxy: "https://plausible.io/**" }
|
|
314
|
-
}
|
|
315
|
-
},
|
|
316
|
-
cloudflareWebAnalytics: {
|
|
317
|
-
privacy: { ip: false, userAgent: false, language: false, screen: false, timezone: false, hardware: false },
|
|
318
|
-
rewrite: [
|
|
319
|
-
{ from: "static.cloudflareinsights.com", to: `${collectPrefix}/cfwa` },
|
|
320
|
-
{ from: "cloudflareinsights.com", to: `${collectPrefix}/cfwa-beacon` }
|
|
321
|
-
],
|
|
322
|
-
routes: {
|
|
323
|
-
[`${collectPrefix}/cfwa/**`]: { proxy: "https://static.cloudflareinsights.com/**" },
|
|
324
|
-
[`${collectPrefix}/cfwa-beacon/**`]: { proxy: "https://cloudflareinsights.com/**" }
|
|
325
|
-
}
|
|
326
|
-
},
|
|
327
|
-
rybbit: {
|
|
328
|
-
privacy: { ip: false, userAgent: false, language: false, screen: false, timezone: false, hardware: false },
|
|
329
|
-
rewrite: [
|
|
330
|
-
{ from: "app.rybbit.io", to: `${collectPrefix}/rybbit` }
|
|
331
|
-
],
|
|
332
|
-
routes: {
|
|
333
|
-
[`${collectPrefix}/rybbit/**`]: { proxy: "https://app.rybbit.io/**" }
|
|
82
|
+
const DEVTOOLS_UI_ROUTE = "/__nuxt-scripts";
|
|
83
|
+
const DEVTOOLS_UI_LOCAL_PORT = 3030;
|
|
84
|
+
const DEVTOOLS_API_STATE_ROUTE = "/__nuxt-scripts-api/state";
|
|
85
|
+
async function setupDevtools(nuxt, options = {}) {
|
|
86
|
+
const { addCustomTab } = await import('@nuxt/devtools-kit');
|
|
87
|
+
const { resolve } = createResolver(import.meta.url);
|
|
88
|
+
const clientPath = resolve("../dist/devtools-client");
|
|
89
|
+
const isProductionBuild = existsSync(clientPath);
|
|
90
|
+
if (isProductionBuild) {
|
|
91
|
+
nuxt.hook("vite:serverCreated", async (server) => {
|
|
92
|
+
const sirv = await import('sirv').then((r) => r.default || r);
|
|
93
|
+
server.middlewares.use(DEVTOOLS_UI_ROUTE, sirv(clientPath, { dev: true, single: true }));
|
|
94
|
+
});
|
|
95
|
+
} else {
|
|
96
|
+
extendViteConfig((config) => {
|
|
97
|
+
config.server = config.server || {};
|
|
98
|
+
config.server.proxy = config.server.proxy || {};
|
|
99
|
+
config.server.proxy[DEVTOOLS_UI_ROUTE] = {
|
|
100
|
+
target: `http://localhost:${DEVTOOLS_UI_LOCAL_PORT}${DEVTOOLS_UI_ROUTE}`,
|
|
101
|
+
changeOrigin: true,
|
|
102
|
+
followRedirects: true,
|
|
103
|
+
rewrite: (path) => path.replace(DEVTOOLS_UI_ROUTE, "")
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
if (options.standalone) {
|
|
108
|
+
setupStandaloneApi(nuxt);
|
|
109
|
+
}
|
|
110
|
+
addCustomTab({
|
|
111
|
+
name: "nuxt-scripts",
|
|
112
|
+
title: "Scripts",
|
|
113
|
+
icon: "carbon:script",
|
|
114
|
+
view: {
|
|
115
|
+
type: "iframe",
|
|
116
|
+
src: DEVTOOLS_UI_ROUTE
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
function setupStandaloneApi(nuxt) {
|
|
121
|
+
let scriptsState = {
|
|
122
|
+
scripts: {},
|
|
123
|
+
updatedAt: 0
|
|
124
|
+
};
|
|
125
|
+
nuxt.hook("vite:serverCreated", (server) => {
|
|
126
|
+
server.middlewares.use(DEVTOOLS_API_STATE_ROUTE, (req, res) => {
|
|
127
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
128
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
129
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
130
|
+
if (req.method === "OPTIONS") {
|
|
131
|
+
res.statusCode = 204;
|
|
132
|
+
res.end();
|
|
133
|
+
return;
|
|
334
134
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
{ from: "cloud.umami.is", to: `${collectPrefix}/umami` }
|
|
340
|
-
],
|
|
341
|
-
routes: {
|
|
342
|
-
[`${collectPrefix}/umami/**`]: { proxy: "https://cloud.umami.is/**" }
|
|
135
|
+
if (req.method === "GET") {
|
|
136
|
+
res.setHeader("Content-Type", "application/json");
|
|
137
|
+
res.end(JSON.stringify(scriptsState));
|
|
138
|
+
return;
|
|
343
139
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
140
|
+
if (req.method === "POST") {
|
|
141
|
+
let body = "";
|
|
142
|
+
req.on("data", (chunk) => {
|
|
143
|
+
body += chunk.toString();
|
|
144
|
+
});
|
|
145
|
+
req.on("end", () => {
|
|
146
|
+
try {
|
|
147
|
+
const data = JSON.parse(body);
|
|
148
|
+
scriptsState = { ...data, updatedAt: Date.now() };
|
|
149
|
+
res.statusCode = 200;
|
|
150
|
+
res.end("ok");
|
|
151
|
+
} catch {
|
|
152
|
+
res.statusCode = 400;
|
|
153
|
+
res.end("invalid json");
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
return;
|
|
354
157
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
158
|
+
res.statusCode = 405;
|
|
159
|
+
res.end("method not allowed");
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
function computeDevtoolsPrivacyLevel(privacy) {
|
|
164
|
+
const flags = Object.values(privacy);
|
|
165
|
+
if (flags.every(Boolean))
|
|
166
|
+
return "full";
|
|
167
|
+
if (flags.some(Boolean))
|
|
168
|
+
return "partial";
|
|
169
|
+
return "none";
|
|
170
|
+
}
|
|
171
|
+
function buildDevtoolsEntry(key, script, configKey, proxyConfig) {
|
|
172
|
+
const privacy = proxyConfig.privacy;
|
|
173
|
+
const normalizedPrivacy = {
|
|
174
|
+
ip: !!privacy.ip,
|
|
175
|
+
userAgent: !!privacy.userAgent,
|
|
176
|
+
language: !!privacy.language,
|
|
177
|
+
screen: !!privacy.screen,
|
|
178
|
+
timezone: !!privacy.timezone,
|
|
179
|
+
hardware: !!privacy.hardware
|
|
180
|
+
};
|
|
181
|
+
const logo = script.logo;
|
|
182
|
+
const logoStr = typeof logo === "object" ? logo.dark || logo.light : logo || "";
|
|
183
|
+
return {
|
|
184
|
+
registryKey: key,
|
|
185
|
+
label: script.label || key,
|
|
186
|
+
logo: logoStr,
|
|
187
|
+
category: script.category || "unknown",
|
|
188
|
+
configKey,
|
|
189
|
+
mechanism: script.src === false ? "config-injection-proxy" : "bundle-rewrite-intercept",
|
|
190
|
+
hasAutoInject: !!proxyConfig.autoInject,
|
|
191
|
+
autoInjectField: proxyConfig.autoInject?.configField,
|
|
192
|
+
hasPostProcess: !!proxyConfig.sdkPatches?.length,
|
|
193
|
+
privacy: normalizedPrivacy,
|
|
194
|
+
privacyLevel: computeDevtoolsPrivacyLevel(normalizedPrivacy),
|
|
195
|
+
domains: [...proxyConfig.domains]
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
function buildDevtoolsData(proxyPrefix, privacyLabel, scripts) {
|
|
199
|
+
const allDomains = /* @__PURE__ */ new Set();
|
|
200
|
+
for (const s of scripts) {
|
|
201
|
+
for (const d of s.domains)
|
|
202
|
+
allDomains.add(d);
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
enabled: true,
|
|
206
|
+
proxyPrefix,
|
|
207
|
+
privacyMode: privacyLabel,
|
|
208
|
+
scripts,
|
|
209
|
+
totalDomains: allDomains.size
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const isStackblitz = provider === "stackblitz";
|
|
214
|
+
async function promptToInstall(name, installCommand, options) {
|
|
215
|
+
if (await resolvePackageJSON(name).catch(() => null))
|
|
216
|
+
return true;
|
|
217
|
+
logger$1.info(`Package ${name} is missing`);
|
|
218
|
+
if (isCI)
|
|
219
|
+
return false;
|
|
220
|
+
if (options.prompt === true || options.prompt !== false && !isStackblitz) {
|
|
221
|
+
const confirm = await logger$1.prompt(`Do you want to install ${name} package?`, {
|
|
222
|
+
type: "confirm",
|
|
223
|
+
name: "confirm",
|
|
224
|
+
initial: true
|
|
225
|
+
});
|
|
226
|
+
if (!confirm)
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
logger$1.info(`Installing ${name}...`);
|
|
230
|
+
try {
|
|
231
|
+
await installCommand();
|
|
232
|
+
logger$1.success(`Installed ${name}`);
|
|
233
|
+
return true;
|
|
234
|
+
} catch (err) {
|
|
235
|
+
logger$1.error(err);
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
const installPrompts = /* @__PURE__ */ new Set();
|
|
240
|
+
function installNuxtModule(name, options) {
|
|
241
|
+
if (installPrompts.has(name))
|
|
242
|
+
return;
|
|
243
|
+
installPrompts.add(name);
|
|
244
|
+
const nuxt = tryUseNuxt();
|
|
245
|
+
if (!nuxt)
|
|
246
|
+
return;
|
|
247
|
+
return promptToInstall(name, async () => {
|
|
248
|
+
const { runCommand } = await import(String("nuxi"));
|
|
249
|
+
await runCommand("module", ["add", name, "--cwd", nuxt.options.rootDir]);
|
|
250
|
+
}, { rootDir: nuxt.options.rootDir, searchPaths: nuxt.options.modulesDir, ...options });
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const logger = useLogger("@nuxt/scripts");
|
|
254
|
+
|
|
255
|
+
const SCRIPT_OPTION_KEYS = ["trigger", "proxy", "bundle", "partytown"];
|
|
256
|
+
function extractRequiredFields(schema) {
|
|
257
|
+
if (!schema)
|
|
258
|
+
return [];
|
|
259
|
+
return Object.entries(schema.entries).filter(([, field]) => field?.type !== "optional").map(([key]) => key);
|
|
260
|
+
}
|
|
261
|
+
function migrateDeprecatedRegistryKeys(registry, warn) {
|
|
262
|
+
for (const key of Object.keys(registry)) {
|
|
263
|
+
const entry = registry[key];
|
|
264
|
+
if (!entry || typeof entry !== "object")
|
|
265
|
+
continue;
|
|
266
|
+
if (Array.isArray(entry)) {
|
|
267
|
+
const opts = entry[1];
|
|
268
|
+
if (opts && typeof opts === "object" && "reverseProxyIntercept" in opts) {
|
|
269
|
+
warn(`[nuxt-scripts] registry.${key}: \`reverseProxyIntercept\` has been renamed to \`proxy\`. Please update your config. Auto-migrating for now.`);
|
|
270
|
+
const o = opts;
|
|
271
|
+
o.proxy ??= o.reverseProxyIntercept;
|
|
272
|
+
delete o.reverseProxyIntercept;
|
|
363
273
|
}
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
{ from: "api-iam.eu.intercom.io", to: `${collectPrefix}/intercom-api-eu` },
|
|
371
|
-
{ from: "api-iam.au.intercom.io", to: `${collectPrefix}/intercom-api-au` }
|
|
372
|
-
],
|
|
373
|
-
routes: {
|
|
374
|
-
[`${collectPrefix}/intercom/**`]: { proxy: "https://widget.intercom.io/**" },
|
|
375
|
-
[`${collectPrefix}/intercom-api/**`]: { proxy: "https://api-iam.intercom.io/**" },
|
|
376
|
-
[`${collectPrefix}/intercom-api-eu/**`]: { proxy: "https://api-iam.eu.intercom.io/**" },
|
|
377
|
-
[`${collectPrefix}/intercom-api-au/**`]: { proxy: "https://api-iam.au.intercom.io/**" }
|
|
274
|
+
} else {
|
|
275
|
+
const obj = entry;
|
|
276
|
+
if ("reverseProxyIntercept" in obj) {
|
|
277
|
+
warn(`[nuxt-scripts] registry.${key}: \`reverseProxyIntercept\` has been renamed to \`proxy\`. Please update your config. Auto-migrating for now.`);
|
|
278
|
+
obj.proxy ??= obj.reverseProxyIntercept;
|
|
279
|
+
delete obj.reverseProxyIntercept;
|
|
378
280
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
routes: {
|
|
386
|
-
[`${collectPrefix}/crisp/**`]: { proxy: "https://client.crisp.chat/**" }
|
|
281
|
+
const so = obj.scriptOptions;
|
|
282
|
+
if (so && typeof so === "object" && "reverseProxyIntercept" in so) {
|
|
283
|
+
warn(`[nuxt-scripts] registry.${key}: \`scriptOptions.reverseProxyIntercept\` has been renamed to \`proxy\`. Please update your config. Auto-migrating for now.`);
|
|
284
|
+
const s = so;
|
|
285
|
+
s.proxy ??= s.reverseProxyIntercept;
|
|
286
|
+
delete s.reverseProxyIntercept;
|
|
387
287
|
}
|
|
388
288
|
}
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
function getProxyConfig(key, collectPrefix) {
|
|
392
|
-
const configs = buildProxyConfig(collectPrefix);
|
|
393
|
-
return configs[key];
|
|
394
|
-
}
|
|
395
|
-
function getAllProxyConfigs(collectPrefix) {
|
|
396
|
-
return buildProxyConfig(collectPrefix);
|
|
289
|
+
}
|
|
397
290
|
}
|
|
398
|
-
function
|
|
399
|
-
const
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
291
|
+
function normalizeRegistryConfig(registry, warn) {
|
|
292
|
+
for (const key of Object.keys(registry)) {
|
|
293
|
+
const entry = registry[key];
|
|
294
|
+
if (!entry) {
|
|
295
|
+
delete registry[key];
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
if (entry === true) {
|
|
299
|
+
warn?.(`[nuxt-scripts] registry.${key}: \`true\` shorthand is deprecated. Use \`{ trigger: 'onNuxtReady' }\` instead.`);
|
|
300
|
+
registry[key] = [{}, { trigger: "onNuxtReady" }];
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
if (entry === "proxy-only") {
|
|
304
|
+
throw new Error(
|
|
305
|
+
`[nuxt-scripts] registry.${key}: \`'proxy-only'\` is no longer supported. Use \`{}\` instead (infrastructure only is now the default behavior).`
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
if (entry === "mock") {
|
|
309
|
+
registry[key] = [{}, { trigger: "manual", skipValidation: true }];
|
|
310
|
+
} else if (Array.isArray(entry)) {
|
|
311
|
+
if (!entry[0] && !entry[1]) {
|
|
312
|
+
delete registry[key];
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
if (!entry[0])
|
|
316
|
+
entry[0] = {};
|
|
317
|
+
} else if (typeof entry === "object") {
|
|
318
|
+
const { scriptOptions, ...rest } = entry;
|
|
319
|
+
const input = {};
|
|
320
|
+
const mergedScriptOptions = {};
|
|
321
|
+
if (scriptOptions && typeof scriptOptions === "object")
|
|
322
|
+
Object.assign(mergedScriptOptions, scriptOptions);
|
|
323
|
+
for (const [k, v] of Object.entries(rest)) {
|
|
324
|
+
if (SCRIPT_OPTION_KEYS.includes(k))
|
|
325
|
+
mergedScriptOptions[k] = v;
|
|
326
|
+
else
|
|
327
|
+
input[k] = v;
|
|
328
|
+
}
|
|
329
|
+
registry[key] = Object.keys(mergedScriptOptions).length > 0 ? [input, mergedScriptOptions] : [input];
|
|
330
|
+
} else {
|
|
331
|
+
delete registry[key];
|
|
407
332
|
}
|
|
408
333
|
}
|
|
409
|
-
return rules;
|
|
410
334
|
}
|
|
411
335
|
|
|
412
336
|
function isVue(id, opts = {}) {
|
|
@@ -430,12 +354,131 @@ function isVue(id, opts = {}) {
|
|
|
430
354
|
}
|
|
431
355
|
return true;
|
|
432
356
|
}
|
|
433
|
-
const JS_RE = /\.(?:[cm]?j|t)sx?$/;
|
|
357
|
+
const JS_RE$1 = /\.(?:[cm]?j|t)sx?$/;
|
|
434
358
|
function isJS(id) {
|
|
435
359
|
const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href));
|
|
436
|
-
return JS_RE.test(pathname);
|
|
360
|
+
return JS_RE$1.test(pathname);
|
|
437
361
|
}
|
|
438
362
|
|
|
363
|
+
const VUE_RE$1 = /\.vue/;
|
|
364
|
+
function NuxtScriptsCheckScripts() {
|
|
365
|
+
return createUnplugin(() => {
|
|
366
|
+
return {
|
|
367
|
+
name: "nuxt-scripts:check-scripts",
|
|
368
|
+
transform: {
|
|
369
|
+
filter: {
|
|
370
|
+
id: VUE_RE$1
|
|
371
|
+
},
|
|
372
|
+
handler(code, id) {
|
|
373
|
+
if (!isVue(id, { type: ["script"] }))
|
|
374
|
+
return;
|
|
375
|
+
if (!code.includes("useScript"))
|
|
376
|
+
return;
|
|
377
|
+
let nameNode;
|
|
378
|
+
let errorNode;
|
|
379
|
+
parseAndWalk(code, id, (_node) => {
|
|
380
|
+
if (_node.type === "VariableDeclaration" && _node.declarations?.[0]?.id?.type === "ObjectPattern") {
|
|
381
|
+
const objPattern = _node.declarations[0]?.id;
|
|
382
|
+
for (const property of objPattern.properties) {
|
|
383
|
+
if (property.type === "Property" && property.key.type === "Identifier" && property.key.name === "$script" && property.value.type === "Identifier") {
|
|
384
|
+
nameNode = _node;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (nameNode) {
|
|
389
|
+
let sequence = _node.type === "SequenceExpression" ? _node : null;
|
|
390
|
+
let assignmentExpression;
|
|
391
|
+
if (_node.type === "VariableDeclaration") {
|
|
392
|
+
if (_node.declarations[0]?.init?.type === "SequenceExpression") {
|
|
393
|
+
sequence = _node.declarations[0]?.init;
|
|
394
|
+
assignmentExpression = _node.declarations[0]?.init?.expressions?.[0];
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
if (sequence && !assignmentExpression) {
|
|
398
|
+
assignmentExpression = sequence.expressions[0]?.type === "AssignmentExpression" ? sequence.expressions[0] : null;
|
|
399
|
+
}
|
|
400
|
+
if (assignmentExpression) {
|
|
401
|
+
const right = assignmentExpression?.right;
|
|
402
|
+
if (right.callee?.name === "_withAsyncContext") {
|
|
403
|
+
if (right.arguments[0]?.body?.name === "$script" || right.arguments[0]?.body?.callee?.object?.name === "$script") {
|
|
404
|
+
errorNode = nameNode;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
if (errorNode) {
|
|
411
|
+
return this.error(new Error("You can't use a top-level await on $script as it will never resolve."));
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
function generateInterceptPluginContents(proxyPrefix) {
|
|
420
|
+
return `export default defineNuxtPlugin({
|
|
421
|
+
name: 'nuxt-scripts:intercept',
|
|
422
|
+
enforce: 'pre',
|
|
423
|
+
setup() {
|
|
424
|
+
const proxyPrefix = ${JSON.stringify(proxyPrefix)};
|
|
425
|
+
const origBeacon = typeof navigator !== 'undefined' && navigator.sendBeacon
|
|
426
|
+
? navigator.sendBeacon.bind(navigator)
|
|
427
|
+
: () => false;
|
|
428
|
+
const origFetch = globalThis.fetch.bind(globalThis);
|
|
429
|
+
|
|
430
|
+
function proxyUrl(url) {
|
|
431
|
+
try {
|
|
432
|
+
const parsed = new URL(url, location.origin);
|
|
433
|
+
if (parsed.origin !== location.origin)
|
|
434
|
+
return location.origin + proxyPrefix + '/' + parsed.host + parsed.pathname + parsed.search;
|
|
435
|
+
} catch {}
|
|
436
|
+
return url;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// XMLHttpRequest wrapper \u2014 intercepts .open() to rewrite URL
|
|
440
|
+
const OrigXHR = XMLHttpRequest;
|
|
441
|
+
class ProxiedXHR extends OrigXHR {
|
|
442
|
+
open() {
|
|
443
|
+
const args = Array.from(arguments);
|
|
444
|
+
if (typeof args[1] === 'string') args[1] = proxyUrl(args[1]);
|
|
445
|
+
return super.open.apply(this, args);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
// Image wrapper \u2014 intercepts .src setter to rewrite URL
|
|
449
|
+
const OrigImage = Image;
|
|
450
|
+
const origSrcDesc = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype, 'src');
|
|
451
|
+
function ProxiedImage(w, h) {
|
|
452
|
+
const img = arguments.length === 2 ? new OrigImage(w, h)
|
|
453
|
+
: arguments.length === 1 ? new OrigImage(w) : new OrigImage();
|
|
454
|
+
if (origSrcDesc && origSrcDesc.set) {
|
|
455
|
+
Object.defineProperty(img, 'src', {
|
|
456
|
+
get() { return origSrcDesc.get.call(this); },
|
|
457
|
+
set(v) { origSrcDesc.set.call(this, typeof v === 'string' ? proxyUrl(v) : v); },
|
|
458
|
+
configurable: true,
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
return img;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
globalThis.__nuxtScripts = {
|
|
465
|
+
sendBeacon: (url, data) => origBeacon(proxyUrl(url), data),
|
|
466
|
+
fetch: (url, opts) => {
|
|
467
|
+
if (typeof url === 'string') return origFetch(proxyUrl(url), opts);
|
|
468
|
+
if (url instanceof Request) return origFetch(new Request(proxyUrl(url.url), url), opts);
|
|
469
|
+
return origFetch(url, opts);
|
|
470
|
+
},
|
|
471
|
+
XMLHttpRequest: ProxiedXHR,
|
|
472
|
+
Image: ProxiedImage,
|
|
473
|
+
};
|
|
474
|
+
},
|
|
475
|
+
})
|
|
476
|
+
`;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
const WORD_OR_DOLLAR_RE = /[\w$]/;
|
|
480
|
+
const PROTOCOL_PREFIX_RE = /^https?:$/;
|
|
481
|
+
const BLANK_CANVAS_DATA_URL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIHWNgAAIABQABNjN9GQAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAAA0lEQVQI12NgYGBgAAAABQABXvMqOgAAAABJRU5ErkJggg==";
|
|
439
482
|
function isPropertyKeyAST(parent, ctx) {
|
|
440
483
|
return parent?.type === "Property" && ctx.key === "key" || parent?.type === "SwitchCase" && ctx.key === "test";
|
|
441
484
|
}
|
|
@@ -445,7 +488,8 @@ function matchAndRewrite(value, rewrites) {
|
|
|
445
488
|
const fromSlashIdx = from.indexOf("/");
|
|
446
489
|
const fromHost = fromSlashIdx > 0 ? from.slice(0, fromSlashIdx) : from;
|
|
447
490
|
const fromPath = fromSlashIdx > 0 ? from.slice(fromSlashIdx) : "";
|
|
448
|
-
if (!value.includes(fromHost))
|
|
491
|
+
if (!value.includes(fromHost))
|
|
492
|
+
continue;
|
|
449
493
|
const url = parseURL(value);
|
|
450
494
|
let shouldRewrite = false;
|
|
451
495
|
let rewriteSuffix = "";
|
|
@@ -488,63 +532,240 @@ function matchAndRewrite(value, rewrites) {
|
|
|
488
532
|
}
|
|
489
533
|
return null;
|
|
490
534
|
}
|
|
491
|
-
|
|
535
|
+
const WINDOW_GLOBALS = /* @__PURE__ */ new Set(["window", "self", "globalThis"]);
|
|
536
|
+
const NAVIGATOR_GLOBALS = /* @__PURE__ */ new Set(["navigator"]);
|
|
537
|
+
function resolveToGlobal(name, scopeTracker, depth = 0) {
|
|
538
|
+
if (depth > 10)
|
|
539
|
+
return null;
|
|
540
|
+
const decl = scopeTracker.getDeclaration(name);
|
|
541
|
+
if (!decl)
|
|
542
|
+
return name;
|
|
543
|
+
if (decl instanceof ScopeTrackerFunctionParam)
|
|
544
|
+
return null;
|
|
545
|
+
if (decl instanceof ScopeTrackerVariable) {
|
|
546
|
+
const declarators = decl.variableNode.declarations;
|
|
547
|
+
if (!declarators)
|
|
548
|
+
return null;
|
|
549
|
+
for (const declarator of declarators) {
|
|
550
|
+
const id = declarator.id;
|
|
551
|
+
if (!id || id.name !== name)
|
|
552
|
+
continue;
|
|
553
|
+
const init = declarator.init;
|
|
554
|
+
if (!init)
|
|
555
|
+
return null;
|
|
556
|
+
if (init.type === "Identifier")
|
|
557
|
+
return resolveToGlobal(init.name, scopeTracker, depth + 1);
|
|
558
|
+
if (init.type === "MemberExpression" && init.object?.type === "Identifier") {
|
|
559
|
+
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;
|
|
560
|
+
if (!memberProp)
|
|
561
|
+
return null;
|
|
562
|
+
const objGlobal = resolveToGlobal(init.object.name, scopeTracker, depth + 1);
|
|
563
|
+
if (!objGlobal)
|
|
564
|
+
return null;
|
|
565
|
+
if (WINDOW_GLOBALS.has(objGlobal) || objGlobal === "document")
|
|
566
|
+
return memberProp;
|
|
567
|
+
return null;
|
|
568
|
+
}
|
|
569
|
+
return null;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return null;
|
|
573
|
+
}
|
|
574
|
+
function resolveCalleeTarget(callee, scopeTracker) {
|
|
575
|
+
if (callee?.type !== "MemberExpression")
|
|
576
|
+
return null;
|
|
577
|
+
const propName = callee.computed ? callee.property?.type === "Literal" && typeof callee.property.value === "string" ? callee.property.value : null : callee.property?.name;
|
|
578
|
+
if (!propName)
|
|
579
|
+
return null;
|
|
580
|
+
const obj = callee.object;
|
|
581
|
+
if (!obj || obj.type !== "Identifier")
|
|
582
|
+
return null;
|
|
583
|
+
const resolved = resolveToGlobal(obj.name, scopeTracker);
|
|
584
|
+
if (!resolved)
|
|
585
|
+
return null;
|
|
586
|
+
if (propName === "fetch" && WINDOW_GLOBALS.has(resolved))
|
|
587
|
+
return "fetch";
|
|
588
|
+
if (propName === "sendBeacon" && (NAVIGATOR_GLOBALS.has(resolved) || WINDOW_GLOBALS.has(resolved)))
|
|
589
|
+
return "sendBeacon";
|
|
590
|
+
if (propName === "sendBeacon" && resolved === "navigator")
|
|
591
|
+
return "sendBeacon";
|
|
592
|
+
if (propName === "XMLHttpRequest" && WINDOW_GLOBALS.has(resolved))
|
|
593
|
+
return "XMLHttpRequest";
|
|
594
|
+
if (propName === "Image" && WINDOW_GLOBALS.has(resolved))
|
|
595
|
+
return "Image";
|
|
596
|
+
return null;
|
|
597
|
+
}
|
|
598
|
+
function rewriteScriptUrlsAST(content, filename, rewrites, sdkPatches, options) {
|
|
492
599
|
const s = new MagicString(content);
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
if (node.type === "TemplateLiteral" && node.expressions?.length === 0) {
|
|
506
|
-
const quasis = node.quasis;
|
|
507
|
-
if (quasis?.length === 1) {
|
|
508
|
-
const value = quasis[0].value?.cooked ?? quasis[0].value?.raw;
|
|
509
|
-
if (typeof value !== "string") return;
|
|
600
|
+
function needsLeadingSpace(start) {
|
|
601
|
+
const prev = content[start - 1];
|
|
602
|
+
return prev && WORD_OR_DOLLAR_RE.test(prev) ? " " : "";
|
|
603
|
+
}
|
|
604
|
+
const scopeTracker = new ScopeTracker({ preserveExitedScopes: true });
|
|
605
|
+
const { program } = parseAndWalk(content, filename, { scopeTracker });
|
|
606
|
+
scopeTracker.freeze();
|
|
607
|
+
walk(program, {
|
|
608
|
+
scopeTracker,
|
|
609
|
+
enter(node, parent, ctx) {
|
|
610
|
+
if (node.type === "Literal" && typeof node.value === "string") {
|
|
611
|
+
const value = node.value;
|
|
510
612
|
const rewritten = matchAndRewrite(value, rewrites);
|
|
511
|
-
if (rewritten === null)
|
|
613
|
+
if (rewritten === null)
|
|
614
|
+
return;
|
|
615
|
+
const quote = content[node.start];
|
|
512
616
|
if (isPropertyKeyAST(parent, ctx)) {
|
|
513
|
-
s.overwrite(node.start, node.end,
|
|
617
|
+
s.overwrite(node.start, node.end, quote + rewritten + quote);
|
|
618
|
+
} else if (value.startsWith("//") && parent?.type === "BinaryExpression" && parent.operator === "+") {
|
|
619
|
+
const sibling = ctx.key === "right" ? parent.left : parent.right;
|
|
620
|
+
if (sibling?.type === "Literal" && typeof sibling.value === "string" && PROTOCOL_PREFIX_RE.test(sibling.value)) {
|
|
621
|
+
s.overwrite(parent.start, parent.end, `${needsLeadingSpace(parent.start)}self.location.origin+${quote}${rewritten}${quote}`);
|
|
622
|
+
} else {
|
|
623
|
+
s.overwrite(node.start, node.end, `${needsLeadingSpace(node.start)}self.location.origin+${quote}${rewritten}${quote}`);
|
|
624
|
+
}
|
|
514
625
|
} else {
|
|
515
|
-
s.overwrite(node.start, node.end,
|
|
626
|
+
s.overwrite(node.start, node.end, `${needsLeadingSpace(node.start)}self.location.origin+${quote}${rewritten}${quote}`);
|
|
516
627
|
}
|
|
517
628
|
}
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
629
|
+
if (node.type === "TemplateLiteral") {
|
|
630
|
+
const quasis = node.quasis;
|
|
631
|
+
const expressions = node.expressions;
|
|
632
|
+
if (expressions?.length === 0 && quasis?.length === 1) {
|
|
633
|
+
const value = quasis[0].value?.cooked ?? quasis[0].value?.raw;
|
|
634
|
+
if (typeof value !== "string")
|
|
635
|
+
return;
|
|
636
|
+
const rewritten = matchAndRewrite(value, rewrites);
|
|
637
|
+
if (rewritten === null)
|
|
638
|
+
return;
|
|
639
|
+
if (isPropertyKeyAST(parent, ctx)) {
|
|
640
|
+
s.overwrite(node.start, node.end, `\`${rewritten}\``);
|
|
641
|
+
} else {
|
|
642
|
+
s.overwrite(node.start, node.end, `${needsLeadingSpace(node.start)}self.location.origin+\`${rewritten}\``);
|
|
643
|
+
}
|
|
644
|
+
} else if (expressions?.length > 0 && quasis?.length > 0) {
|
|
645
|
+
const firstQuasi = quasis[0];
|
|
646
|
+
const value = firstQuasi.value?.cooked ?? firstQuasi.value?.raw;
|
|
647
|
+
if (typeof value !== "string" || isPropertyKeyAST(parent, ctx))
|
|
648
|
+
return;
|
|
649
|
+
const rewritten = matchAndRewrite(value, rewrites);
|
|
650
|
+
if (rewritten === null)
|
|
651
|
+
return;
|
|
652
|
+
s.overwrite(node.start, firstQuasi.end, `${needsLeadingSpace(node.start)}self.location.origin+\`${rewritten}`);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
if (node.type === "CallExpression" && !options?.skipApiRewrites) {
|
|
656
|
+
const callee = node.callee;
|
|
657
|
+
const shouldNeutralizeCanvas = options?.neutralizeCanvas !== false;
|
|
658
|
+
const canvasPropName = shouldNeutralizeCanvas && callee?.type === "MemberExpression" ? callee.computed ? callee.property?.type === "Literal" && typeof callee.property.value === "string" ? callee.property.value : null : callee.property?.name : null;
|
|
659
|
+
if (canvasPropName === "toDataURL" && callee.object) {
|
|
660
|
+
const blankCanvas = `"${BLANK_CANVAS_DATA_URL}"`;
|
|
661
|
+
if (callee.object.type === "Identifier") {
|
|
662
|
+
const decl = scopeTracker.getDeclaration(callee.object.name);
|
|
663
|
+
if (decl instanceof ScopeTrackerFunction || decl instanceof ScopeTrackerIdentifier) ; else {
|
|
664
|
+
s.overwrite(node.start, node.end, blankCanvas);
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
} else {
|
|
668
|
+
s.overwrite(node.start, node.end, blankCanvas);
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
if (canvasPropName === "getExtension") {
|
|
673
|
+
const args = node.arguments;
|
|
674
|
+
if (args?.length === 1 && args[0]?.type === "Literal" && args[0].value === "WEBGL_debug_renderer_info") {
|
|
675
|
+
s.overwrite(node.start, node.end, "null");
|
|
676
|
+
return;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
if (callee?.type === "Identifier" && callee.name === "fetch") {
|
|
680
|
+
if (!scopeTracker.getDeclaration("fetch"))
|
|
681
|
+
s.overwrite(callee.start, callee.end, "__nuxtScripts.fetch");
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
const target = resolveCalleeTarget(callee, scopeTracker);
|
|
685
|
+
if (target === "fetch" || target === "sendBeacon") {
|
|
686
|
+
s.overwrite(callee.start, callee.end, `__nuxtScripts.${target}`);
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
if (callee?.type === "MemberExpression" && !callee.computed && callee.property?.name === "sendBeacon" && callee.object?.type === "Identifier") {
|
|
690
|
+
const resolved = resolveToGlobal(callee.object.name, scopeTracker);
|
|
691
|
+
if (resolved === null) {
|
|
692
|
+
s.overwrite(callee.start, callee.end, "__nuxtScripts.sendBeacon");
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
if (sdkPatches?.some((p) => p.type === "neutralize-domain-check") && node.type === "BinaryExpression" && node.operator === "<") {
|
|
697
|
+
const left = node.left;
|
|
698
|
+
const right = node.right;
|
|
699
|
+
if (right?.type === "Literal" && right.value === 0 && left?.type === "CallExpression" && left.callee?.type === "MemberExpression") {
|
|
700
|
+
const prop = left.callee.computed ? left.callee.property?.type === "Literal" && typeof left.callee.property.value === "string" ? left.callee.property.value : null : left.callee.property?.name;
|
|
701
|
+
if (prop === "indexOf" && left.arguments?.length === 1) {
|
|
702
|
+
const arg = left.arguments[0];
|
|
703
|
+
if (arg?.type === "Literal" && typeof arg.value === "string" && rewrites.some((r) => arg.value.includes(r.from))) {
|
|
704
|
+
s.overwrite(right.start, right.end, "-1");
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
}
|
|
523
708
|
}
|
|
524
|
-
if (
|
|
525
|
-
|
|
709
|
+
if (sdkPatches?.some((p) => p.type === "replace-src-split") && node.type === "MemberExpression" && node.computed) {
|
|
710
|
+
const prop = node.property;
|
|
711
|
+
const obj = node.object;
|
|
712
|
+
if (prop?.type === "Literal" && prop.value === 0 && obj?.type === "CallExpression" && obj.callee?.type === "MemberExpression") {
|
|
713
|
+
const callProp = obj.callee.computed ? obj.callee.property?.type === "Literal" && typeof obj.callee.property.value === "string" ? obj.callee.property.value : null : obj.callee.property?.name;
|
|
714
|
+
if (callProp === "split" && obj.arguments?.length === 1) {
|
|
715
|
+
const arg = obj.arguments[0];
|
|
716
|
+
if (arg?.type === "Literal" && typeof arg.value === "string") {
|
|
717
|
+
for (const patch of sdkPatches) {
|
|
718
|
+
if (patch.type !== "replace-src-split" || patch.separator !== arg.value)
|
|
719
|
+
continue;
|
|
720
|
+
const rewrite = rewrites.find((r) => r.from === patch.fromDomain);
|
|
721
|
+
if (!rewrite)
|
|
722
|
+
continue;
|
|
723
|
+
const proxyPath = patch.appendPath ? `${rewrite.to}/${patch.appendPath}` : rewrite.to;
|
|
724
|
+
s.overwrite(node.start, node.end, `${needsLeadingSpace(node.start)}self.location.origin+"${proxyPath}"`);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}
|
|
526
729
|
}
|
|
527
|
-
if (
|
|
528
|
-
|
|
730
|
+
if (node.type === "NewExpression" && !options?.skipApiRewrites) {
|
|
731
|
+
const callee = node.callee;
|
|
732
|
+
if (callee?.type === "Identifier" && callee.name === "XMLHttpRequest") {
|
|
733
|
+
if (!scopeTracker.getDeclaration("XMLHttpRequest"))
|
|
734
|
+
s.overwrite(callee.start, callee.end, "__nuxtScripts.XMLHttpRequest");
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
if (callee?.type === "Identifier" && callee.name === "Image") {
|
|
738
|
+
if (!scopeTracker.getDeclaration("Image"))
|
|
739
|
+
s.overwrite(callee.start, callee.end, "__nuxtScripts.Image");
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
const target = resolveCalleeTarget(callee, scopeTracker);
|
|
743
|
+
if (target === "XMLHttpRequest" || target === "Image") {
|
|
744
|
+
s.overwrite(callee.start, callee.end, `__nuxtScripts.${target}`);
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
if (callee?.type === "MemberExpression" && callee.object?.type === "Identifier") {
|
|
748
|
+
const propName = callee.computed ? callee.property?.type === "Literal" && typeof callee.property.value === "string" ? callee.property.value : null : callee.property?.name;
|
|
749
|
+
if (propName === "XMLHttpRequest" || propName === "Image") {
|
|
750
|
+
const resolved = resolveToGlobal(callee.object.name, scopeTracker);
|
|
751
|
+
if (resolved === null) {
|
|
752
|
+
s.overwrite(callee.start, callee.end, `__nuxtScripts.${propName}`);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}
|
|
529
756
|
}
|
|
530
757
|
}
|
|
531
758
|
});
|
|
532
|
-
|
|
533
|
-
const gaRewrite = rewrites.find((r) => r.from.includes("google-analytics.com/g/collect"));
|
|
534
|
-
if (gaRewrite) {
|
|
535
|
-
output = output.replace(
|
|
536
|
-
/"https:\/\/"\+\(.*?\)\+"\.google-analytics\.com\/g\/collect"/g,
|
|
537
|
-
`self.location.origin+"${gaRewrite.to}"`
|
|
538
|
-
);
|
|
539
|
-
output = output.replace(
|
|
540
|
-
/"https:\/\/"\+\(.*?\)\+"\.analytics\.google\.com\/g\/collect"/g,
|
|
541
|
-
`self.location.origin+"${gaRewrite.to}"`
|
|
542
|
-
);
|
|
543
|
-
}
|
|
544
|
-
return output;
|
|
759
|
+
return s.toString();
|
|
545
760
|
}
|
|
546
761
|
|
|
547
762
|
const SEVEN_DAYS_IN_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
763
|
+
const PROTOCOL_RELATIVE_RE = /^\/\//;
|
|
764
|
+
const VUE_RE = /\.vue/;
|
|
765
|
+
const JS_RE = /\.[cm]?[jt]sx?$/;
|
|
766
|
+
const TEST_RE = /\.(?:test|spec)\./;
|
|
767
|
+
const UPPERCASE_RE = /^[A-Z]$/;
|
|
768
|
+
const USE_SCRIPT_RE = /^useScript/;
|
|
548
769
|
function calculateIntegrity(content, algorithm = "sha384") {
|
|
549
770
|
const hash = createHash(algorithm).update(content).digest("base64");
|
|
550
771
|
return `${algorithm}-${hash}`;
|
|
@@ -557,9 +778,9 @@ async function isCacheExpired(storage, filename, cacheMaxAge = SEVEN_DAYS_IN_MS)
|
|
|
557
778
|
}
|
|
558
779
|
return Date.now() - meta.timestamp > cacheMaxAge;
|
|
559
780
|
}
|
|
560
|
-
function normalizeScriptData(src, assetsBaseURL = "/_scripts") {
|
|
781
|
+
function normalizeScriptData(src, assetsBaseURL = "/_scripts/assets") {
|
|
561
782
|
if (hasProtocol(src, { acceptRelative: true })) {
|
|
562
|
-
src = src.replace(
|
|
783
|
+
src = src.replace(PROTOCOL_RELATIVE_RE, "https://");
|
|
563
784
|
const url = parseURL(src);
|
|
564
785
|
const h = hash(url);
|
|
565
786
|
const file = `${h.startsWith("-") ? `_${h.slice(1)}` : h}.js`;
|
|
@@ -571,7 +792,7 @@ function normalizeScriptData(src, assetsBaseURL = "/_scripts") {
|
|
|
571
792
|
return { url: src };
|
|
572
793
|
}
|
|
573
794
|
async function downloadScript(opts, renderedScript, fetchOptions, cacheMaxAge) {
|
|
574
|
-
const { src, url, filename, forceDownload, integrity, proxyRewrites } = opts;
|
|
795
|
+
const { src, url, filename, forceDownload, integrity, proxyRewrites, sdkPatches, skipApiRewrites, neutralizeCanvas } = opts;
|
|
575
796
|
if (src === url || !filename) {
|
|
576
797
|
return;
|
|
577
798
|
}
|
|
@@ -609,7 +830,7 @@ async function downloadScript(opts, renderedScript, fetchOptions, cacheMaxAge) {
|
|
|
609
830
|
await storage.setItemRaw(`bundle:${filename}`, res);
|
|
610
831
|
if (proxyRewrites?.length && res) {
|
|
611
832
|
const content = res.toString("utf-8");
|
|
612
|
-
const rewritten = rewriteScriptUrlsAST(content, filename || "script.js", proxyRewrites);
|
|
833
|
+
const rewritten = rewriteScriptUrlsAST(content, filename || "script.js", proxyRewrites, sdkPatches, { skipApiRewrites, neutralizeCanvas });
|
|
613
834
|
res = Buffer.from(rewritten, "utf-8");
|
|
614
835
|
logger.debug(`Rewrote ${proxyRewrites.length} URL patterns in ${filename}`);
|
|
615
836
|
}
|
|
@@ -666,8 +887,8 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
666
887
|
transform: {
|
|
667
888
|
filter: {
|
|
668
889
|
id: {
|
|
669
|
-
include: [
|
|
670
|
-
exclude: [
|
|
890
|
+
include: [VUE_RE, JS_RE],
|
|
891
|
+
exclude: [TEST_RE]
|
|
671
892
|
}
|
|
672
893
|
},
|
|
673
894
|
async handler(code, id) {
|
|
@@ -677,11 +898,11 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
677
898
|
return;
|
|
678
899
|
const s = new MagicString(code);
|
|
679
900
|
const deferredOps = [];
|
|
680
|
-
parseAndWalk(code, id,
|
|
901
|
+
parseAndWalk(code, id, (_node) => {
|
|
681
902
|
const calleeName = _node.callee?.name;
|
|
682
903
|
if (!calleeName)
|
|
683
904
|
return;
|
|
684
|
-
const isValidCallee = calleeName === "useScript" || calleeName?.startsWith("useScript") &&
|
|
905
|
+
const isValidCallee = calleeName === "useScript" || calleeName?.startsWith("useScript") && UPPERCASE_RE.test(calleeName?.charAt(9)) && !calleeName.startsWith("useScriptTrigger") && !calleeName.startsWith("useScriptEvent");
|
|
685
906
|
if (_node.type === "CallExpression" && _node.callee.type === "Identifier" && isValidCallee) {
|
|
686
907
|
const fnName = _node.callee?.name;
|
|
687
908
|
const node = _node;
|
|
@@ -689,7 +910,7 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
689
910
|
let src;
|
|
690
911
|
let registryKey;
|
|
691
912
|
if (fnName !== "useScript") {
|
|
692
|
-
const baseName = fnName.replace(
|
|
913
|
+
const baseName = fnName.replace(USE_SCRIPT_RE, "");
|
|
693
914
|
registryKey = baseName.length > 0 ? baseName.charAt(0).toLowerCase() + baseName.slice(1) : void 0;
|
|
694
915
|
}
|
|
695
916
|
if (fnName === "useScript") {
|
|
@@ -706,7 +927,8 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
706
927
|
if (!registryNode) {
|
|
707
928
|
return;
|
|
708
929
|
}
|
|
709
|
-
|
|
930
|
+
const bundleResolve = getBundleResolve(registryNode);
|
|
931
|
+
if (!bundleResolve && !registryNode.src)
|
|
710
932
|
return;
|
|
711
933
|
const registryConfig = options.registryConfig?.[registryKey || ""] || {};
|
|
712
934
|
const fnArg0 = {};
|
|
@@ -725,7 +947,7 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
725
947
|
}
|
|
726
948
|
if (!scriptSrcNode) {
|
|
727
949
|
const mergedOptions = { ...registryConfig, ...fnArg0 };
|
|
728
|
-
src =
|
|
950
|
+
src = bundleResolve && bundleResolve(mergedOptions);
|
|
729
951
|
if (src === false)
|
|
730
952
|
return;
|
|
731
953
|
if (!src && registryNode.src)
|
|
@@ -753,8 +975,9 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
753
975
|
if (scriptSrcNode || src) {
|
|
754
976
|
src = src || (typeof scriptSrcNode?.value === "string" ? scriptSrcNode?.value : false);
|
|
755
977
|
if (src) {
|
|
756
|
-
|
|
757
|
-
let
|
|
978
|
+
const registryScript = fnName !== "useScript" ? options.scripts?.find((s2) => s2.import.name === fnName) : void 0;
|
|
979
|
+
let canBundle = !!registryScript?.bundle;
|
|
980
|
+
let forceDownload = false;
|
|
758
981
|
if (node.arguments[1]?.type === "ObjectExpression") {
|
|
759
982
|
const scriptOptionsArg = node.arguments[1];
|
|
760
983
|
const bundleProperty = scriptOptionsArg.properties.find(
|
|
@@ -789,31 +1012,39 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
789
1012
|
canBundle = bundleValue === true || bundleValue === "force" || String(bundleValue) === "true";
|
|
790
1013
|
forceDownload = bundleValue === "force";
|
|
791
1014
|
}
|
|
792
|
-
const
|
|
793
|
-
return prop.type === "Property" && prop.key?.name === "
|
|
1015
|
+
const rpiOption = scriptOptions?.value.properties?.find((prop) => {
|
|
1016
|
+
return prop.type === "Property" && prop.key?.name === "proxy" && prop.value.type === "Literal";
|
|
794
1017
|
});
|
|
795
|
-
let firstPartyOptOut =
|
|
1018
|
+
let firstPartyOptOut = rpiOption?.value.value === false;
|
|
796
1019
|
if (!firstPartyOptOut && node.arguments[1]?.type === "ObjectExpression") {
|
|
797
|
-
const
|
|
798
|
-
(p) => p.type === "Property" && p.key?.name === "
|
|
1020
|
+
const secondArgProp = node.arguments[1].properties.find(
|
|
1021
|
+
(p) => p.type === "Property" && p.key?.name === "proxy" && p.value.type === "Literal"
|
|
799
1022
|
);
|
|
800
|
-
firstPartyOptOut =
|
|
1023
|
+
firstPartyOptOut = secondArgProp?.value.value === false;
|
|
801
1024
|
}
|
|
802
1025
|
if (!firstPartyOptOut && node.arguments[0]?.type === "ObjectExpression") {
|
|
803
|
-
const
|
|
804
|
-
(p) => p.type === "Property" && p.key?.name === "
|
|
1026
|
+
const firstArgProp = node.arguments[0].properties.find(
|
|
1027
|
+
(p) => p.type === "Property" && p.key?.name === "proxy" && p.value.type === "Literal"
|
|
805
1028
|
);
|
|
806
|
-
firstPartyOptOut =
|
|
1029
|
+
firstPartyOptOut = firstArgProp?.value.value === false;
|
|
807
1030
|
}
|
|
808
1031
|
if (canBundle) {
|
|
809
1032
|
const { url: _url, filename } = normalizeScriptData(src, options.assetsBaseURL);
|
|
810
1033
|
const script = options.scripts?.find((s2) => s2.import.name === fnName);
|
|
811
|
-
const
|
|
812
|
-
const
|
|
1034
|
+
const hasReverseProxy = !!script?.proxy;
|
|
1035
|
+
const proxyConfigKey = hasReverseProxy ? typeof script?.proxy === "string" ? script.proxy : registryKey : void 0;
|
|
1036
|
+
const proxyConfig = !firstPartyOptOut && proxyConfigKey ? options.proxyConfigs?.[proxyConfigKey] : void 0;
|
|
1037
|
+
const proxyRewrites = proxyConfig?.domains?.map((domain) => ({
|
|
1038
|
+
from: domain,
|
|
1039
|
+
to: `${options.proxyPrefix}/${domain}`
|
|
1040
|
+
}));
|
|
1041
|
+
const sdkPatches = proxyConfig?.sdkPatches;
|
|
1042
|
+
const skipApiRewrites = !!(registryKey && options.partytownScripts?.has(registryKey));
|
|
1043
|
+
const neutralizeCanvas = proxyConfig?.privacy !== void 0 && typeof proxyConfig.privacy === "object" ? proxyConfig.privacy.hardware ?? true : true;
|
|
813
1044
|
deferredOps.push(async () => {
|
|
814
1045
|
let url = _url;
|
|
815
1046
|
try {
|
|
816
|
-
await downloadScript({ src, url, filename, forceDownload, proxyRewrites, integrity: options.integrity }, renderedScript, options.fetchOptions, options.cacheMaxAge);
|
|
1047
|
+
await downloadScript({ src, url, filename, forceDownload, proxyRewrites, sdkPatches, integrity: options.integrity, skipApiRewrites, neutralizeCanvas }, renderedScript, options.fetchOptions, options.cacheMaxAge);
|
|
817
1048
|
} catch (e) {
|
|
818
1049
|
if (options.fallbackOnSrcOnBundleFail) {
|
|
819
1050
|
logger.warn(`[Nuxt Scripts: Bundle Transformer] Failed to bundle ${src}. Fallback to remote loading.`);
|
|
@@ -893,113 +1124,15 @@ function NuxtScriptBundleTransformer(options = {
|
|
|
893
1124
|
});
|
|
894
1125
|
}
|
|
895
1126
|
|
|
896
|
-
const
|
|
897
|
-
|
|
898
|
-
if (await resolvePackageJSON(name).catch(() => null))
|
|
899
|
-
return true;
|
|
900
|
-
logger$1.info(`Package ${name} is missing`);
|
|
901
|
-
if (isCI)
|
|
902
|
-
return false;
|
|
903
|
-
if (options.prompt === true || options.prompt !== false && !isStackblitz) {
|
|
904
|
-
const confirm = await logger$1.prompt(`Do you want to install ${name} package?`, {
|
|
905
|
-
type: "confirm",
|
|
906
|
-
name: "confirm",
|
|
907
|
-
initial: true
|
|
908
|
-
});
|
|
909
|
-
if (!confirm)
|
|
910
|
-
return false;
|
|
911
|
-
}
|
|
912
|
-
logger$1.info(`Installing ${name}...`);
|
|
913
|
-
try {
|
|
914
|
-
await installCommand();
|
|
915
|
-
logger$1.success(`Installed ${name}`);
|
|
916
|
-
return true;
|
|
917
|
-
} catch (err) {
|
|
918
|
-
logger$1.error(err);
|
|
919
|
-
return false;
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
const installPrompts = /* @__PURE__ */ new Set();
|
|
923
|
-
function installNuxtModule(name, options) {
|
|
924
|
-
if (installPrompts.has(name))
|
|
925
|
-
return;
|
|
926
|
-
installPrompts.add(name);
|
|
927
|
-
const nuxt = tryUseNuxt();
|
|
928
|
-
if (!nuxt)
|
|
929
|
-
return;
|
|
930
|
-
return promptToInstall(name, async () => {
|
|
931
|
-
const { runCommand } = await import(String("nuxi"));
|
|
932
|
-
await runCommand("module", ["add", name, "--cwd", nuxt.options.rootDir]);
|
|
933
|
-
}, { rootDir: nuxt.options.rootDir, searchPaths: nuxt.options.modulesDir, ...options });
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
function NuxtScriptsCheckScripts() {
|
|
937
|
-
return createUnplugin(() => {
|
|
938
|
-
return {
|
|
939
|
-
name: "nuxt-scripts:check-scripts",
|
|
940
|
-
transform: {
|
|
941
|
-
filter: {
|
|
942
|
-
id: /\.vue/
|
|
943
|
-
},
|
|
944
|
-
handler(code, id) {
|
|
945
|
-
if (!isVue(id, { type: ["script"] }))
|
|
946
|
-
return;
|
|
947
|
-
if (!code.includes("useScript"))
|
|
948
|
-
return;
|
|
949
|
-
let nameNode;
|
|
950
|
-
let errorNode;
|
|
951
|
-
parseAndWalk(code, id, function(_node) {
|
|
952
|
-
if (_node.type === "VariableDeclaration" && _node.declarations?.[0]?.id?.type === "ObjectPattern") {
|
|
953
|
-
const objPattern = _node.declarations[0]?.id;
|
|
954
|
-
for (const property of objPattern.properties) {
|
|
955
|
-
if (property.type === "Property" && property.key.type === "Identifier" && property.key.name === "$script" && property.value.type === "Identifier") {
|
|
956
|
-
nameNode = _node;
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
if (nameNode) {
|
|
961
|
-
let sequence = _node.type === "SequenceExpression" ? _node : null;
|
|
962
|
-
let assignmentExpression;
|
|
963
|
-
if (_node.type === "VariableDeclaration") {
|
|
964
|
-
if (_node.declarations[0]?.init?.type === "SequenceExpression") {
|
|
965
|
-
sequence = _node.declarations[0]?.init;
|
|
966
|
-
assignmentExpression = _node.declarations[0]?.init?.expressions?.[0];
|
|
967
|
-
}
|
|
968
|
-
}
|
|
969
|
-
if (sequence && !assignmentExpression) {
|
|
970
|
-
assignmentExpression = sequence.expressions[0]?.type === "AssignmentExpression" ? sequence.expressions[0] : null;
|
|
971
|
-
}
|
|
972
|
-
if (assignmentExpression) {
|
|
973
|
-
const right = assignmentExpression?.right;
|
|
974
|
-
if (right.callee?.name === "_withAsyncContext") {
|
|
975
|
-
if (right.arguments[0]?.body?.name === "$script" || right.arguments[0]?.body?.callee?.object?.name === "$script") {
|
|
976
|
-
errorNode = nameNode;
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
});
|
|
982
|
-
if (errorNode) {
|
|
983
|
-
return this.error(new Error("You can't use a top-level await on $script as it will never resolve."));
|
|
984
|
-
}
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
};
|
|
988
|
-
});
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
function registerTypeTemplates({ nuxt, config, newScripts }) {
|
|
1127
|
+
const TRIGGER_PLACEHOLDER_RE = /"__TRIGGER_PLACEHOLDER__"/g;
|
|
1128
|
+
function registerTypeTemplates({ config, newScripts }) {
|
|
992
1129
|
addTypeTemplate({
|
|
993
1130
|
filename: "types/nuxt-scripts-augments.d.ts",
|
|
994
1131
|
getContents: () => {
|
|
995
|
-
const typesPath = relative(
|
|
996
|
-
resolve(nuxt.options.rootDir, nuxt.options.buildDir, "types"),
|
|
997
|
-
resolve("runtime/types")
|
|
998
|
-
);
|
|
999
1132
|
let augments = `// Generated by @nuxt/scripts
|
|
1000
1133
|
declare module '#app' {
|
|
1001
1134
|
interface NuxtApp {
|
|
1002
|
-
$scripts: Record<${[...Object.keys(config.globals || {}), ...Object.keys(config.registry || {})].map((k) => `'${k}'`)
|
|
1135
|
+
$scripts: Record<${[...[...Object.keys(config.globals || {}), ...Object.keys(config.registry || {})].map((k) => `'${k}'`), ...["string"]].join(" | ")}, import('#nuxt-scripts/types').UseScriptContext<any> | undefined>
|
|
1003
1136
|
_scripts: Record<string, import('#nuxt-scripts/types').NuxtDevToolsScriptInstance>
|
|
1004
1137
|
}
|
|
1005
1138
|
interface RuntimeNuxtHooks {
|
|
@@ -1010,12 +1143,11 @@ declare module '#app' {
|
|
|
1010
1143
|
if (newScripts.length) {
|
|
1011
1144
|
augments += `
|
|
1012
1145
|
declare module '#nuxt-scripts/types' {
|
|
1013
|
-
type _NuxtScriptOptions = Omit<import('${typesPath}').NuxtUseScriptOptions, 'use' | 'beforeInit'>
|
|
1014
1146
|
interface ScriptRegistry {
|
|
1015
1147
|
${newScripts.map((i) => {
|
|
1016
1148
|
const key = i.import.name.replace("useScript", "");
|
|
1017
1149
|
const keyLcFirst = key.substring(0, 1).toLowerCase() + key.substring(1);
|
|
1018
|
-
return ` ${keyLcFirst}?: import('${i.import.from}').${key}Input
|
|
1150
|
+
return ` ${keyLcFirst}?: import('${i.import.from}').${key}Input`;
|
|
1019
1151
|
}).join("\n")}
|
|
1020
1152
|
}
|
|
1021
1153
|
}
|
|
@@ -1071,7 +1203,7 @@ function resolveTriggerForTemplate(trigger) {
|
|
|
1071
1203
|
function templatePlugin(config, registry) {
|
|
1072
1204
|
if (Array.isArray(config.globals)) {
|
|
1073
1205
|
config.globals = Object.fromEntries(config.globals.map((i) => [hash(i), i]));
|
|
1074
|
-
logger.warn("The `globals` array option is deprecated
|
|
1206
|
+
logger.warn("The `globals` array option is deprecated. Convert to an object: `globals: { myScript: 'https://example.com/script.js' }`");
|
|
1075
1207
|
}
|
|
1076
1208
|
const imports = [];
|
|
1077
1209
|
const inits = [];
|
|
@@ -1080,29 +1212,30 @@ function templatePlugin(config, registry) {
|
|
|
1080
1212
|
let needsInteractionImport = false;
|
|
1081
1213
|
let needsServiceWorkerImport = false;
|
|
1082
1214
|
for (const [k, c] of Object.entries(config.registry || {})) {
|
|
1215
|
+
if (c === false)
|
|
1216
|
+
continue;
|
|
1217
|
+
const [, scriptOptions] = c;
|
|
1218
|
+
if (!scriptOptions?.trigger)
|
|
1219
|
+
continue;
|
|
1083
1220
|
const importDefinition = registry.find((i) => i.import.name.toLowerCase() === `usescript${k.toLowerCase()}`);
|
|
1084
1221
|
if (importDefinition) {
|
|
1085
1222
|
resolvedRegistryKeys.push(k);
|
|
1086
1223
|
imports.unshift(`import { ${importDefinition.import.name} } from '${importDefinition.import.from}'`);
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
}
|
|
1099
|
-
const args = { ...input, scriptOptions };
|
|
1100
|
-
const argsJson = triggerResolved ? JSON.stringify(args).replace(/"__TRIGGER_PLACEHOLDER__"/g, triggerResolved) : JSON.stringify(args);
|
|
1101
|
-
inits.push(`const ${k} = ${importDefinition.import.name}(${argsJson})`);
|
|
1102
|
-
} else {
|
|
1103
|
-
const args = (typeof c !== "object" ? {} : c) || {};
|
|
1104
|
-
inits.push(`const ${k} = ${importDefinition.import.name}(${JSON.stringify(args)})`);
|
|
1224
|
+
const [input] = c;
|
|
1225
|
+
const opts = { ...scriptOptions };
|
|
1226
|
+
const triggerResolved = resolveTriggerForTemplate(opts.trigger);
|
|
1227
|
+
if (triggerResolved) {
|
|
1228
|
+
opts.trigger = "__TRIGGER_PLACEHOLDER__";
|
|
1229
|
+
if (triggerResolved.includes("useScriptTriggerIdleTimeout"))
|
|
1230
|
+
needsIdleTimeoutImport = true;
|
|
1231
|
+
if (triggerResolved.includes("useScriptTriggerInteraction"))
|
|
1232
|
+
needsInteractionImport = true;
|
|
1233
|
+
if (triggerResolved.includes("useScriptTriggerServiceWorker"))
|
|
1234
|
+
needsServiceWorkerImport = true;
|
|
1105
1235
|
}
|
|
1236
|
+
const args = { ...input, scriptOptions: opts };
|
|
1237
|
+
const argsJson = triggerResolved ? JSON.stringify(args).replace(TRIGGER_PLACEHOLDER_RE, triggerResolved) : JSON.stringify(args);
|
|
1238
|
+
inits.push(`const ${k} = ${importDefinition.import.name}(${argsJson})`);
|
|
1106
1239
|
}
|
|
1107
1240
|
}
|
|
1108
1241
|
for (const [k, c] of Object.entries(config.globals || {})) {
|
|
@@ -1112,11 +1245,14 @@ function templatePlugin(config, registry) {
|
|
|
1112
1245
|
const options = c[1];
|
|
1113
1246
|
const triggerResolved = resolveTriggerForTemplate(options?.trigger);
|
|
1114
1247
|
if (triggerResolved) {
|
|
1115
|
-
if (triggerResolved.includes("useScriptTriggerIdleTimeout"))
|
|
1116
|
-
|
|
1117
|
-
if (triggerResolved.includes("
|
|
1248
|
+
if (triggerResolved.includes("useScriptTriggerIdleTimeout"))
|
|
1249
|
+
needsIdleTimeoutImport = true;
|
|
1250
|
+
if (triggerResolved.includes("useScriptTriggerInteraction"))
|
|
1251
|
+
needsInteractionImport = true;
|
|
1252
|
+
if (triggerResolved.includes("useScriptTriggerServiceWorker"))
|
|
1253
|
+
needsServiceWorkerImport = true;
|
|
1118
1254
|
const resolvedOptions = { ...options, trigger: "__TRIGGER_PLACEHOLDER__" };
|
|
1119
|
-
const optionsJson = JSON.stringify(resolvedOptions).replace(
|
|
1255
|
+
const optionsJson = JSON.stringify(resolvedOptions).replace(TRIGGER_PLACEHOLDER_RE, triggerResolved);
|
|
1120
1256
|
inits.push(`const ${k} = useScript(${JSON.stringify({ key: k, ...typeof c[0] === "string" ? { src: c[0] } : c[0] })}, { ...${optionsJson}, use: () => ({ ${k}: window.${k} }) })`);
|
|
1121
1257
|
} else {
|
|
1122
1258
|
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} }) })`);
|
|
@@ -1124,11 +1260,14 @@ function templatePlugin(config, registry) {
|
|
|
1124
1260
|
} else if (typeof c === "object" && c !== null) {
|
|
1125
1261
|
const triggerResolved = resolveTriggerForTemplate(c.trigger);
|
|
1126
1262
|
if (triggerResolved) {
|
|
1127
|
-
if (triggerResolved.includes("useScriptTriggerIdleTimeout"))
|
|
1128
|
-
|
|
1129
|
-
if (triggerResolved.includes("
|
|
1263
|
+
if (triggerResolved.includes("useScriptTriggerIdleTimeout"))
|
|
1264
|
+
needsIdleTimeoutImport = true;
|
|
1265
|
+
if (triggerResolved.includes("useScriptTriggerInteraction"))
|
|
1266
|
+
needsInteractionImport = true;
|
|
1267
|
+
if (triggerResolved.includes("useScriptTriggerServiceWorker"))
|
|
1268
|
+
needsServiceWorkerImport = true;
|
|
1130
1269
|
const resolvedOptions = { ...c, trigger: "__TRIGGER_PLACEHOLDER__" };
|
|
1131
|
-
const argsJson = JSON.stringify({ key: k, ...resolvedOptions }).replace(
|
|
1270
|
+
const argsJson = JSON.stringify({ key: k, ...resolvedOptions }).replace(TRIGGER_PLACEHOLDER_RE, triggerResolved);
|
|
1132
1271
|
inits.push(`const ${k} = useScript(${argsJson}, { use: () => ({ ${k}: window.${k} }) })`);
|
|
1133
1272
|
} else {
|
|
1134
1273
|
inits.push(`const ${k} = useScript(${JSON.stringify({ key: k, ...c })}, { use: () => ({ ${k}: window.${k} }) })`);
|
|
@@ -1157,7 +1296,7 @@ function templatePlugin(config, registry) {
|
|
|
1157
1296
|
` parallel: true,`,
|
|
1158
1297
|
` setup() {`,
|
|
1159
1298
|
...inits.map((i) => ` ${i}`),
|
|
1160
|
-
` return { provide: {
|
|
1299
|
+
` return { provide: { scripts: { ${[...Object.keys(config.globals || {}), ...resolvedRegistryKeys].join(", ")} } } }`,
|
|
1161
1300
|
` }`,
|
|
1162
1301
|
`})`
|
|
1163
1302
|
].join("\n");
|
|
@@ -1167,22 +1306,28 @@ const SELF_CLOSING_SCRIPT_RE = /<((?:Script[A-Z]|script-)\w[\w-]*)\b([^>]*?)\/\s
|
|
|
1167
1306
|
function fixSelfClosingScriptComponents(nuxt) {
|
|
1168
1307
|
function expandTags(content) {
|
|
1169
1308
|
SELF_CLOSING_SCRIPT_RE.lastIndex = 0;
|
|
1170
|
-
if (!SELF_CLOSING_SCRIPT_RE.test(content))
|
|
1309
|
+
if (!SELF_CLOSING_SCRIPT_RE.test(content))
|
|
1310
|
+
return null;
|
|
1171
1311
|
SELF_CLOSING_SCRIPT_RE.lastIndex = 0;
|
|
1172
1312
|
return content.replace(SELF_CLOSING_SCRIPT_RE, (_, tag, attrs) => `<${tag}${attrs.trimEnd()}></${tag}>`);
|
|
1173
1313
|
}
|
|
1174
1314
|
function fixFile(filePath) {
|
|
1175
|
-
if (!existsSync(filePath))
|
|
1315
|
+
if (!existsSync(filePath))
|
|
1316
|
+
return;
|
|
1176
1317
|
const content = readFileSync(filePath, "utf-8");
|
|
1177
1318
|
const fixed = expandTags(content);
|
|
1178
|
-
if (fixed)
|
|
1319
|
+
if (fixed)
|
|
1320
|
+
nuxt.vfs[filePath] = fixed;
|
|
1179
1321
|
}
|
|
1180
1322
|
function scanDir(dir) {
|
|
1181
|
-
if (!existsSync(dir))
|
|
1323
|
+
if (!existsSync(dir))
|
|
1324
|
+
return;
|
|
1182
1325
|
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
1183
1326
|
const fullPath = resolve(dir, entry.name);
|
|
1184
|
-
if (entry.isDirectory())
|
|
1185
|
-
|
|
1327
|
+
if (entry.isDirectory())
|
|
1328
|
+
scanDir(fullPath);
|
|
1329
|
+
else if (entry.name.endsWith(".vue"))
|
|
1330
|
+
fixFile(fullPath);
|
|
1186
1331
|
}
|
|
1187
1332
|
}
|
|
1188
1333
|
const pagesDirs = /* @__PURE__ */ new Set();
|
|
@@ -1195,7 +1340,8 @@ function fixSelfClosingScriptComponents(nuxt) {
|
|
|
1195
1340
|
for (const dir of pagesDirs) scanDir(dir);
|
|
1196
1341
|
if (nuxt.options.dev) {
|
|
1197
1342
|
nuxt.hook("builder:watch", (_event, relativePath) => {
|
|
1198
|
-
if (!relativePath.endsWith(".vue"))
|
|
1343
|
+
if (!relativePath.endsWith(".vue"))
|
|
1344
|
+
return;
|
|
1199
1345
|
for (const layer of nuxt.options._layers) {
|
|
1200
1346
|
const fullPath = resolve(layer.config.srcDir, relativePath);
|
|
1201
1347
|
for (const dir of pagesDirs) {
|
|
@@ -1208,20 +1354,37 @@ function fixSelfClosingScriptComponents(nuxt) {
|
|
|
1208
1354
|
});
|
|
1209
1355
|
}
|
|
1210
1356
|
}
|
|
1211
|
-
const
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
}
|
|
1357
|
+
const UPPER_RE = /([A-Z])/g;
|
|
1358
|
+
const toScreamingSnake = (s) => s.replace(UPPER_RE, "_$1").toUpperCase();
|
|
1359
|
+
function isProxyDisabled(registryKey, registry2, runtimeConfig) {
|
|
1360
|
+
const entry = registry2?.[registryKey];
|
|
1361
|
+
if (!entry)
|
|
1362
|
+
return true;
|
|
1363
|
+
const [input, scriptOptions] = entry;
|
|
1364
|
+
if (input?.proxy === false || scriptOptions?.proxy === false)
|
|
1365
|
+
return true;
|
|
1366
|
+
if (runtimeConfig) {
|
|
1367
|
+
const rtEntry = runtimeConfig.public?.scripts?.[registryKey];
|
|
1368
|
+
if (rtEntry?.proxy === false)
|
|
1369
|
+
return true;
|
|
1370
|
+
}
|
|
1371
|
+
return false;
|
|
1372
|
+
}
|
|
1373
|
+
function applyAutoInject(registry2, runtimeConfig, proxyPrefix, registryKey, autoInject) {
|
|
1374
|
+
if (isProxyDisabled(registryKey, registry2, runtimeConfig))
|
|
1375
|
+
return;
|
|
1376
|
+
const entry = registry2[registryKey];
|
|
1377
|
+
const input = entry[0];
|
|
1378
|
+
const rtScripts = runtimeConfig.public?.scripts;
|
|
1379
|
+
const rtEntry = rtScripts?.[registryKey];
|
|
1380
|
+
const config = rtEntry && typeof rtEntry === "object" ? rtEntry : input;
|
|
1381
|
+
if (!config || config[autoInject.configField])
|
|
1382
|
+
return;
|
|
1383
|
+
const value = autoInject.computeValue(proxyPrefix, config);
|
|
1384
|
+
input[autoInject.configField] = value;
|
|
1385
|
+
if (rtEntry && typeof rtEntry === "object" && rtEntry !== input)
|
|
1386
|
+
rtEntry[autoInject.configField] = value;
|
|
1387
|
+
}
|
|
1225
1388
|
const module$1 = defineNuxtModule({
|
|
1226
1389
|
meta: {
|
|
1227
1390
|
name: "@nuxt/scripts",
|
|
@@ -1231,7 +1394,6 @@ const module$1 = defineNuxtModule({
|
|
|
1231
1394
|
}
|
|
1232
1395
|
},
|
|
1233
1396
|
defaults: {
|
|
1234
|
-
firstParty: true,
|
|
1235
1397
|
defaultScriptOptions: {
|
|
1236
1398
|
trigger: "onNuxtReady"
|
|
1237
1399
|
},
|
|
@@ -1253,83 +1415,79 @@ const module$1 = defineNuxtModule({
|
|
|
1253
1415
|
debug: false
|
|
1254
1416
|
},
|
|
1255
1417
|
async setup(config, nuxt) {
|
|
1256
|
-
const { resolvePath } = createResolver(import.meta.url);
|
|
1418
|
+
const { resolve: resolveModule, resolvePath } = createResolver(import.meta.url);
|
|
1257
1419
|
const { version, name } = await readPackageJSON(await resolvePath("../package.json"));
|
|
1258
|
-
nuxt.options.alias["#nuxt-scripts-validator"] = await resolvePath(`./runtime/validation/${nuxt.options.dev || nuxt.options._prepare ? "valibot" : "mock"}`);
|
|
1259
1420
|
nuxt.options.alias["#nuxt-scripts"] = await resolvePath("./runtime");
|
|
1260
1421
|
logger.level = config.debug || nuxt.options.debug ? 4 : 3;
|
|
1261
1422
|
if (!config.enabled) {
|
|
1262
1423
|
logger.debug("The module is disabled, skipping setup.");
|
|
1263
1424
|
return;
|
|
1264
1425
|
}
|
|
1426
|
+
if (nuxt.options.dev) {
|
|
1427
|
+
setupDevtools(nuxt, { standalone: config._standaloneDevtools });
|
|
1428
|
+
if (config._standaloneDevtools) {
|
|
1429
|
+
const bridgePath = resolveModule("./runtime/devtools-standalone-bridge.client");
|
|
1430
|
+
addPluginTemplate({
|
|
1431
|
+
filename: "modules/nuxt-scripts/devtools-standalone-bridge.client.mjs",
|
|
1432
|
+
getContents() {
|
|
1433
|
+
return `export { default } from '${bridgePath}'`;
|
|
1434
|
+
}
|
|
1435
|
+
});
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1265
1438
|
const { version: unheadVersion } = await readPackageJSON("@unhead/vue", {
|
|
1266
1439
|
from: nuxt.options.modulesDir
|
|
1267
1440
|
}).catch(() => ({ version: null }));
|
|
1268
1441
|
if (unheadVersion?.startsWith("1")) {
|
|
1269
1442
|
logger.error(`Nuxt Scripts requires Unhead >= 2, you are using v${unheadVersion}. Please run \`nuxi upgrade --clean\` to upgrade...`);
|
|
1270
1443
|
}
|
|
1444
|
+
const scripts = await registry(resolvePath);
|
|
1445
|
+
if (config.registry) {
|
|
1446
|
+
migrateDeprecatedRegistryKeys(config.registry, (msg) => logger.warn(msg));
|
|
1447
|
+
normalizeRegistryConfig(config.registry, (msg) => logger.warn(msg));
|
|
1448
|
+
nuxt.options.runtimeConfig.public = nuxt.options.runtimeConfig.public || {};
|
|
1449
|
+
const registryWithDefaults = {};
|
|
1450
|
+
for (const [key, entry] of Object.entries(config.registry)) {
|
|
1451
|
+
if (entry === false)
|
|
1452
|
+
continue;
|
|
1453
|
+
const input = entry[0];
|
|
1454
|
+
const envDefaults = scripts.find((s) => s.registryKey === key)?.envDefaults;
|
|
1455
|
+
if (!envDefaults || !Object.keys(envDefaults).length) {
|
|
1456
|
+
registryWithDefaults[key] = input;
|
|
1457
|
+
continue;
|
|
1458
|
+
}
|
|
1459
|
+
const envResolved = {};
|
|
1460
|
+
for (const [field, defaultValue] of Object.entries(envDefaults)) {
|
|
1461
|
+
const envKey = `NUXT_PUBLIC_SCRIPTS_${toScreamingSnake(key)}_${toScreamingSnake(field)}`;
|
|
1462
|
+
envResolved[field] = process.env[envKey] || defaultValue;
|
|
1463
|
+
}
|
|
1464
|
+
registryWithDefaults[key] = defu(input, envResolved);
|
|
1465
|
+
}
|
|
1466
|
+
nuxt.options.runtimeConfig.public.scripts = defu(
|
|
1467
|
+
nuxt.options.runtimeConfig.public.scripts || {},
|
|
1468
|
+
registryWithDefaults
|
|
1469
|
+
);
|
|
1470
|
+
}
|
|
1471
|
+
const googleMapsEnabled = config.googleStaticMapsProxy?.enabled || !!config.registry?.googleMaps;
|
|
1271
1472
|
nuxt.options.runtimeConfig["nuxt-scripts"] = {
|
|
1272
1473
|
version,
|
|
1273
1474
|
// Private proxy config with API key (server-side only)
|
|
1274
|
-
googleStaticMapsProxy:
|
|
1475
|
+
googleStaticMapsProxy: googleMapsEnabled ? { apiKey: nuxt.options.runtimeConfig.public.scripts?.googleMaps?.apiKey } : void 0
|
|
1275
1476
|
};
|
|
1276
1477
|
nuxt.options.runtimeConfig.public["nuxt-scripts"] = {
|
|
1277
1478
|
// expose for devtools
|
|
1278
1479
|
version: nuxt.options.dev ? version : void 0,
|
|
1480
|
+
prefix: config.prefix || "/_scripts",
|
|
1279
1481
|
defaultScriptOptions: config.defaultScriptOptions,
|
|
1280
1482
|
// Only expose enabled and cacheMaxAge to client, not apiKey
|
|
1281
|
-
googleStaticMapsProxy:
|
|
1483
|
+
googleStaticMapsProxy: googleMapsEnabled ? { enabled: true, cacheMaxAge: config.googleStaticMapsProxy?.cacheMaxAge ?? 3600 } : void 0
|
|
1282
1484
|
};
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
}
|
|
1290
|
-
if (config.defaultScriptOptions?.bundle !== void 0) {
|
|
1291
|
-
logger.warn(
|
|
1292
|
-
"`scripts.defaultScriptOptions.bundle` is deprecated. Use `scripts.firstParty: true` instead. First-party mode is now enabled by default."
|
|
1293
|
-
);
|
|
1294
|
-
}
|
|
1295
|
-
const staticPresets = ["static", "github-pages", "cloudflare-pages-static"];
|
|
1296
|
-
const preset = process.env.NITRO_PRESET || "";
|
|
1297
|
-
const isStaticPreset = staticPresets.includes(preset);
|
|
1298
|
-
const firstPartyEnabled = !!config.firstParty;
|
|
1299
|
-
const firstPartyPrefix = typeof config.firstParty === "object" ? config.firstParty.prefix : void 0;
|
|
1300
|
-
const firstPartyCollectPrefix = typeof config.firstParty === "object" ? config.firstParty.collectPrefix || "/_proxy" : "/_proxy";
|
|
1301
|
-
const firstPartyPrivacy = typeof config.firstParty === "object" ? config.firstParty.privacy : void 0;
|
|
1302
|
-
const assetsPrefix = firstPartyPrefix || config.assets?.prefix || "/_scripts";
|
|
1303
|
-
if (config.partytown?.length) {
|
|
1304
|
-
config.registry = config.registry || {};
|
|
1305
|
-
const requiredForwards = [];
|
|
1306
|
-
for (const scriptKey of config.partytown) {
|
|
1307
|
-
const forwards = PARTYTOWN_FORWARDS[scriptKey];
|
|
1308
|
-
if (forwards) {
|
|
1309
|
-
requiredForwards.push(...forwards);
|
|
1310
|
-
} else if (import.meta.dev) {
|
|
1311
|
-
logger.warn(`[partytown] "${scriptKey}" has no known Partytown forwards configured. It may not work correctly or may require manual forward configuration.`);
|
|
1312
|
-
}
|
|
1313
|
-
const reg = config.registry;
|
|
1314
|
-
const existing = reg[scriptKey];
|
|
1315
|
-
if (Array.isArray(existing)) {
|
|
1316
|
-
existing[1] = { ...existing[1], partytown: true };
|
|
1317
|
-
} else if (existing && typeof existing === "object" && existing !== true && existing !== "mock") {
|
|
1318
|
-
reg[scriptKey] = [existing, { partytown: true }];
|
|
1319
|
-
} else if (existing === true || existing === "mock") {
|
|
1320
|
-
reg[scriptKey] = [{}, { partytown: true }];
|
|
1321
|
-
} else {
|
|
1322
|
-
reg[scriptKey] = [{}, { partytown: true }];
|
|
1323
|
-
}
|
|
1324
|
-
}
|
|
1325
|
-
if (requiredForwards.length && hasNuxtModule("@nuxtjs/partytown")) {
|
|
1326
|
-
const partytownConfig = nuxt.options.partytown || {};
|
|
1327
|
-
const existingForwards = partytownConfig.forward || [];
|
|
1328
|
-
const newForwards = [.../* @__PURE__ */ new Set([...existingForwards, ...requiredForwards])];
|
|
1329
|
-
nuxt.options.partytown = { ...partytownConfig, forward: newForwards };
|
|
1330
|
-
logger.info(`[partytown] Auto-configured forwards: ${requiredForwards.join(", ")}`);
|
|
1331
|
-
}
|
|
1332
|
-
}
|
|
1485
|
+
const scriptsBase = config.prefix || "/_scripts";
|
|
1486
|
+
const proxyPrefix = `${scriptsBase}/p`;
|
|
1487
|
+
const assetsPrefix = `${scriptsBase}/assets`;
|
|
1488
|
+
const proxyConfigs = {};
|
|
1489
|
+
const proxyHandlerPath = await resolvePath("./runtime/server/proxy-handler");
|
|
1490
|
+
addServerHandler({ route: `${proxyPrefix}/**`, handler: proxyHandlerPath });
|
|
1333
1491
|
const composables = [
|
|
1334
1492
|
"useScript",
|
|
1335
1493
|
"useScriptEventPage",
|
|
@@ -1358,60 +1516,37 @@ const module$1 = defineNuxtModule({
|
|
|
1358
1516
|
return templateTriggerResolver(config.defaultScriptOptions);
|
|
1359
1517
|
}
|
|
1360
1518
|
});
|
|
1361
|
-
logger.debug("[nuxt-scripts]
|
|
1362
|
-
let interceptRules = [];
|
|
1363
|
-
if (firstPartyEnabled) {
|
|
1364
|
-
addPluginTemplate({
|
|
1365
|
-
filename: "nuxt-scripts-intercept.client.mjs",
|
|
1366
|
-
getContents() {
|
|
1367
|
-
const rulesJson = JSON.stringify(interceptRules);
|
|
1368
|
-
return `export default defineNuxtPlugin({
|
|
1369
|
-
name: 'nuxt-scripts:intercept',
|
|
1370
|
-
enforce: 'pre',
|
|
1371
|
-
setup() {
|
|
1372
|
-
const rules = ${rulesJson};
|
|
1373
|
-
const origBeacon = typeof navigator !== 'undefined' && navigator.sendBeacon
|
|
1374
|
-
? navigator.sendBeacon.bind(navigator)
|
|
1375
|
-
: () => false;
|
|
1376
|
-
const origFetch = globalThis.fetch.bind(globalThis);
|
|
1377
|
-
|
|
1378
|
-
function rewriteUrl(url) {
|
|
1379
|
-
try {
|
|
1380
|
-
const parsed = new URL(url, location.origin);
|
|
1381
|
-
for (const rule of rules) {
|
|
1382
|
-
if (parsed.hostname === rule.pattern || parsed.hostname.endsWith('.' + rule.pattern)) {
|
|
1383
|
-
if (rule.pathPrefix && !parsed.pathname.startsWith(rule.pathPrefix)) continue;
|
|
1384
|
-
const path = rule.pathPrefix ? parsed.pathname.slice(rule.pathPrefix.length) : parsed.pathname;
|
|
1385
|
-
return location.origin + rule.target + (path.startsWith('/') ? '' : '/') + path + parsed.search;
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
} catch {}
|
|
1389
|
-
return url;
|
|
1390
|
-
}
|
|
1391
|
-
|
|
1392
|
-
globalThis.__nuxtScripts = {
|
|
1393
|
-
sendBeacon: (url, data) => origBeacon(rewriteUrl(url), data),
|
|
1394
|
-
fetch: (url, opts) => origFetch(typeof url === 'string' ? rewriteUrl(url) : url, opts),
|
|
1395
|
-
};
|
|
1396
|
-
},
|
|
1397
|
-
})
|
|
1398
|
-
`;
|
|
1399
|
-
}
|
|
1400
|
-
});
|
|
1401
|
-
const proxyHandlerPath = await resolvePath("./runtime/server/proxy-handler");
|
|
1402
|
-
logger.debug("[nuxt-scripts] Registering proxy handler:", `${firstPartyCollectPrefix}/**`, "->", proxyHandlerPath);
|
|
1403
|
-
addServerHandler({
|
|
1404
|
-
route: `${firstPartyCollectPrefix}/**`,
|
|
1405
|
-
handler: proxyHandlerPath
|
|
1406
|
-
});
|
|
1407
|
-
}
|
|
1408
|
-
const scripts = await registry(resolvePath);
|
|
1519
|
+
logger.debug("[nuxt-scripts] Proxy prefix:", proxyPrefix);
|
|
1409
1520
|
for (const script of scripts) {
|
|
1410
1521
|
if (script.import?.name) {
|
|
1411
1522
|
addImports({ priority: 2, ...script.import });
|
|
1412
1523
|
script._importRegistered = true;
|
|
1413
1524
|
}
|
|
1414
1525
|
}
|
|
1526
|
+
if (config.registry) {
|
|
1527
|
+
for (const [key, entry] of Object.entries(config.registry)) {
|
|
1528
|
+
if (!entry)
|
|
1529
|
+
continue;
|
|
1530
|
+
const [input, scriptOptions] = entry;
|
|
1531
|
+
if (scriptOptions?.skipValidation)
|
|
1532
|
+
continue;
|
|
1533
|
+
const script = scripts.find((s) => s.registryKey === key);
|
|
1534
|
+
if (!script?.schema)
|
|
1535
|
+
continue;
|
|
1536
|
+
const requiredFields = extractRequiredFields(script.schema);
|
|
1537
|
+
const missing = requiredFields.filter((f) => !input[f]);
|
|
1538
|
+
if (missing.length) {
|
|
1539
|
+
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"}.`);
|
|
1540
|
+
}
|
|
1541
|
+
const envDefaultKeys = new Set(Object.keys(script.envDefaults || {}));
|
|
1542
|
+
const userProvidedFields = Object.keys(input).filter((f) => !envDefaultKeys.has(f));
|
|
1543
|
+
if (userProvidedFields.length > 0 && (!scriptOptions || !("trigger" in scriptOptions))) {
|
|
1544
|
+
logger.warn(
|
|
1545
|
+
`[nuxt-scripts] registry.${key}: config provided without a \`trigger\`. The script will not auto-load. Add \`trigger: 'onNuxtReady'\` to auto-load, or \`trigger: false\` for infrastructure only. See https://scripts.nuxt.com/docs/migration-guide/v0-to-v1`
|
|
1546
|
+
);
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1415
1550
|
nuxt.hooks.hook("modules:done", async () => {
|
|
1416
1551
|
const registryScripts = [...scripts];
|
|
1417
1552
|
await nuxt.hooks.callHook("scripts:registry", registryScripts);
|
|
@@ -1422,7 +1557,7 @@ const module$1 = defineNuxtModule({
|
|
|
1422
1557
|
}
|
|
1423
1558
|
const registryScriptsWithImport = registryScripts.filter((i) => !!i.import?.name);
|
|
1424
1559
|
const newScripts = registryScriptsWithImport.filter((i) => !scripts.some((r) => r.import?.name === i.import.name));
|
|
1425
|
-
registerTypeTemplates({
|
|
1560
|
+
registerTypeTemplates({ config, newScripts });
|
|
1426
1561
|
if (Object.keys(config.globals || {}).length || Object.keys(config.registry || {}).length) {
|
|
1427
1562
|
addPluginTemplate({
|
|
1428
1563
|
filename: `modules/${name.replace("/", "-")}/plugin.mjs`,
|
|
@@ -1431,79 +1566,123 @@ const module$1 = defineNuxtModule({
|
|
|
1431
1566
|
}
|
|
1432
1567
|
});
|
|
1433
1568
|
}
|
|
1434
|
-
const { renderedScript } = setupPublicAssetStrategy(
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1569
|
+
const { renderedScript } = setupPublicAssetStrategy(assetsPrefix);
|
|
1570
|
+
const scriptByKey = /* @__PURE__ */ new Map();
|
|
1571
|
+
for (const script of registryScripts) {
|
|
1572
|
+
if (script.registryKey)
|
|
1573
|
+
scriptByKey.set(script.registryKey, script);
|
|
1574
|
+
}
|
|
1575
|
+
const partytownScripts = /* @__PURE__ */ new Set();
|
|
1576
|
+
let anyNeedsProxy = false;
|
|
1577
|
+
const registryKeys = Object.keys(config.registry || {});
|
|
1578
|
+
for (const key of registryKeys) {
|
|
1579
|
+
const script = scriptByKey.get(key);
|
|
1580
|
+
if (!script)
|
|
1581
|
+
continue;
|
|
1582
|
+
const entry = config.registry?.[key];
|
|
1583
|
+
const scriptOptions = entry?.[1] || {};
|
|
1584
|
+
const inputOptions = entry?.[0] || {};
|
|
1585
|
+
const mergedOverrides = { ...inputOptions, ...scriptOptions };
|
|
1586
|
+
const resolved = resolveCapabilities(script, mergedOverrides);
|
|
1587
|
+
if (resolved.proxy)
|
|
1588
|
+
anyNeedsProxy = true;
|
|
1589
|
+
if (resolved.partytown) {
|
|
1590
|
+
partytownScripts.add(key);
|
|
1591
|
+
const forwards = getPartytownForwards(script);
|
|
1592
|
+
if (forwards?.length && hasNuxtModule("@nuxtjs/partytown")) {
|
|
1593
|
+
const partytownConfig = nuxt.options.partytown || {};
|
|
1594
|
+
const existingForwards = partytownConfig.forward || [];
|
|
1595
|
+
const newForwards = [.../* @__PURE__ */ new Set([...existingForwards, ...forwards])];
|
|
1596
|
+
nuxt.options.partytown = { ...partytownConfig, forward: newForwards };
|
|
1597
|
+
} else if (!forwards?.length && import.meta.dev) {
|
|
1598
|
+
logger.warn(`[partytown] "${key}" has no known Partytown forwards configured. It may not work correctly or may require manual forward configuration.`);
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
if (anyNeedsProxy) {
|
|
1603
|
+
const builtConfigs = buildProxyConfigsFromRegistry(registryScripts, scriptByKey);
|
|
1604
|
+
Object.assign(proxyConfigs, builtConfigs);
|
|
1605
|
+
const domainPrivacy = {};
|
|
1440
1606
|
const unsupportedScripts = [];
|
|
1607
|
+
const unmatchedScripts = [];
|
|
1608
|
+
let totalDomains = 0;
|
|
1609
|
+
const devtoolsScripts = [];
|
|
1441
1610
|
for (const key of registryKeys) {
|
|
1442
|
-
const script =
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
if (proxyConfig?.routes) {
|
|
1447
|
-
Object.assign(neededRoutes, proxyConfig.routes);
|
|
1448
|
-
for (const routePath of Object.keys(proxyConfig.routes)) {
|
|
1449
|
-
routePrivacyOverrides[routePath] = proxyConfig.privacy;
|
|
1450
|
-
}
|
|
1451
|
-
} else {
|
|
1452
|
-
unsupportedScripts.push(key);
|
|
1453
|
-
}
|
|
1611
|
+
const script = scriptByKey.get(key);
|
|
1612
|
+
if (!script) {
|
|
1613
|
+
unmatchedScripts.push(key);
|
|
1614
|
+
continue;
|
|
1454
1615
|
}
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1616
|
+
if (!script.proxy)
|
|
1617
|
+
continue;
|
|
1618
|
+
if (isProxyDisabled(key, config.registry))
|
|
1619
|
+
continue;
|
|
1620
|
+
const configKey = typeof script.proxy === "string" ? script.proxy : key;
|
|
1621
|
+
const proxyConfig = proxyConfigs[configKey];
|
|
1622
|
+
if (!proxyConfig) {
|
|
1623
|
+
unsupportedScripts.push(key);
|
|
1624
|
+
continue;
|
|
1625
|
+
}
|
|
1626
|
+
const entry = config.registry?.[key];
|
|
1627
|
+
const inputPrivacy = entry?.[0]?.privacy;
|
|
1628
|
+
for (const domain of proxyConfig.domains) {
|
|
1629
|
+
domainPrivacy[domain] = inputPrivacy ?? proxyConfig.privacy;
|
|
1630
|
+
totalDomains++;
|
|
1461
1631
|
}
|
|
1632
|
+
if (proxyConfig.autoInject && config.registry)
|
|
1633
|
+
applyAutoInject(config.registry, nuxt.options.runtimeConfig, proxyPrefix, key, proxyConfig.autoInject);
|
|
1634
|
+
if (nuxt.options.dev)
|
|
1635
|
+
devtoolsScripts.push(buildDevtoolsEntry(key, script, configKey, proxyConfig));
|
|
1462
1636
|
}
|
|
1463
|
-
if (
|
|
1637
|
+
if (unmatchedScripts.length) {
|
|
1464
1638
|
logger.warn(
|
|
1465
|
-
`
|
|
1466
|
-
|
|
1639
|
+
`Proxy mode: could not find registry scripts for: ${unmatchedScripts.join(", ")}.
|
|
1640
|
+
These scripts will not have proxy routes registered.`
|
|
1467
1641
|
);
|
|
1468
1642
|
}
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1643
|
+
if (unsupportedScripts.length && nuxt.options.dev) {
|
|
1644
|
+
logger.warn(
|
|
1645
|
+
`Proxy mode is enabled but these scripts don't support it yet: ${unsupportedScripts.join(", ")}.
|
|
1646
|
+
They will load directly from third-party servers.`
|
|
1647
|
+
);
|
|
1473
1648
|
}
|
|
1649
|
+
addPluginTemplate({
|
|
1650
|
+
filename: "nuxt-scripts-intercept.client.mjs",
|
|
1651
|
+
getContents() {
|
|
1652
|
+
return generateInterceptPluginContents(proxyPrefix);
|
|
1653
|
+
}
|
|
1654
|
+
});
|
|
1474
1655
|
nuxt.options.runtimeConfig["nuxt-scripts-proxy"] = {
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
routePrivacy: routePrivacyOverrides
|
|
1479
|
-
// per-script privacy from registry
|
|
1656
|
+
proxyPrefix,
|
|
1657
|
+
domainPrivacy,
|
|
1658
|
+
privacy: config.privacy
|
|
1480
1659
|
};
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
const scriptsCount = registryKeys.length;
|
|
1485
|
-
const privacyLabel = firstPartyPrivacy === void 0 ? "per-script" : typeof firstPartyPrivacy === "boolean" ? firstPartyPrivacy ? "anonymize" : "passthrough" : "custom";
|
|
1486
|
-
logger.success(`First-party mode enabled for ${scriptsCount} script(s), ${routeCount} proxy route(s) configured (privacy: ${privacyLabel})`);
|
|
1487
|
-
if (logger.level >= 4) {
|
|
1488
|
-
for (const [path, config2] of Object.entries(neededRoutes)) {
|
|
1489
|
-
logger.debug(` ${path} \u2192 ${config2.proxy}`);
|
|
1490
|
-
}
|
|
1491
|
-
}
|
|
1492
|
-
}
|
|
1660
|
+
const privacyLabel = config.privacy === void 0 ? "per-script" : typeof config.privacy === "boolean" ? config.privacy ? "anonymize" : "passthrough" : "custom";
|
|
1661
|
+
if (totalDomains > 0 && nuxt.options.dev) {
|
|
1662
|
+
logger.success(`Proxy mode enabled for ${registryKeys.length} script(s), ${totalDomains} domain(s) proxied (privacy: ${privacyLabel})`);
|
|
1493
1663
|
}
|
|
1494
|
-
|
|
1664
|
+
const staticPresets = ["static", "github-pages", "cloudflare-pages-static", "netlify-static", "azure-static", "firebase-static"];
|
|
1665
|
+
const preset = process.env.NITRO_PRESET || "";
|
|
1666
|
+
if (staticPresets.includes(preset)) {
|
|
1495
1667
|
logger.warn(
|
|
1496
|
-
`
|
|
1668
|
+
`Proxy collection endpoints require a server runtime (detected: ${preset || "static"}).
|
|
1497
1669
|
Scripts will be bundled, but collection requests will not be proxied.
|
|
1498
|
-
|
|
1499
|
-
Options:
|
|
1500
|
-
1. Configure platform rewrites (Vercel, Netlify, Cloudflare)
|
|
1501
|
-
2. Switch to server-rendered mode (ssr: true)
|
|
1502
|
-
3. Disable with firstParty: false
|
|
1503
|
-
|
|
1504
|
-
See: https://scripts.nuxt.com/docs/guides/first-party#static-hosting`
|
|
1670
|
+
Options: configure platform rewrites, switch to server-rendered mode, or disable with proxy: false.`
|
|
1505
1671
|
);
|
|
1506
1672
|
}
|
|
1673
|
+
if (nuxt.options.dev) {
|
|
1674
|
+
nuxt.options.runtimeConfig.public["nuxt-scripts-devtools"] = buildDevtoolsData(proxyPrefix, privacyLabel, devtoolsScripts);
|
|
1675
|
+
}
|
|
1676
|
+
if (partytownScripts.size && hasNuxtModule("@nuxtjs/partytown")) {
|
|
1677
|
+
const partytownConfig = nuxt.options.partytown || {};
|
|
1678
|
+
if (!partytownConfig.resolveUrl) {
|
|
1679
|
+
partytownConfig.resolveUrl = generatePartytownResolveUrl(proxyPrefix);
|
|
1680
|
+
nuxt.options.partytown = partytownConfig;
|
|
1681
|
+
logger.info("[partytown] Auto-configured resolveUrl for proxy");
|
|
1682
|
+
} else {
|
|
1683
|
+
logger.warn("[partytown] Custom resolveUrl already set. Add proxy rules to your resolveUrl manually.");
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1507
1686
|
}
|
|
1508
1687
|
const moduleInstallPromises = /* @__PURE__ */ new Map();
|
|
1509
1688
|
addBuildPlugin(NuxtScriptsCheckScripts(), {
|
|
@@ -1512,9 +1691,9 @@ See: https://scripts.nuxt.com/docs/guides/first-party#static-hosting`
|
|
|
1512
1691
|
addBuildPlugin(NuxtScriptBundleTransformer({
|
|
1513
1692
|
scripts: registryScriptsWithImport,
|
|
1514
1693
|
registryConfig: nuxt.options.runtimeConfig.public.scripts,
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1694
|
+
proxyConfigs,
|
|
1695
|
+
proxyPrefix,
|
|
1696
|
+
partytownScripts,
|
|
1518
1697
|
moduleDetected(module) {
|
|
1519
1698
|
if (nuxt.options.dev && module !== "@nuxt/scripts" && !moduleInstallPromises.has(module) && !hasNuxtModule(module))
|
|
1520
1699
|
moduleInstallPromises.set(module, () => installNuxtModule(module));
|
|
@@ -1527,41 +1706,46 @@ See: https://scripts.nuxt.com/docs/guides/first-party#static-hosting`
|
|
|
1527
1706
|
renderedScript
|
|
1528
1707
|
}));
|
|
1529
1708
|
nuxt.hooks.hook("build:done", async () => {
|
|
1530
|
-
const initPromise =
|
|
1709
|
+
const initPromise = [...moduleInstallPromises.values()];
|
|
1531
1710
|
for (const p of initPromise)
|
|
1532
1711
|
await p?.();
|
|
1533
1712
|
});
|
|
1534
1713
|
});
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1714
|
+
const scriptsPrefix = config.prefix || "/_scripts";
|
|
1715
|
+
const enabledEndpoints = {};
|
|
1716
|
+
for (const script of scripts) {
|
|
1717
|
+
if (!script.serverHandlers?.length || !script.registryKey)
|
|
1718
|
+
continue;
|
|
1719
|
+
const isEnabled = script.registryKey === "googleMaps" ? config.googleStaticMapsProxy?.enabled || config.registry?.googleMaps : config.registry?.[script.registryKey];
|
|
1720
|
+
if (!isEnabled)
|
|
1721
|
+
continue;
|
|
1722
|
+
enabledEndpoints[script.registryKey] = true;
|
|
1723
|
+
for (const handler of script.serverHandlers) {
|
|
1724
|
+
addServerHandler({
|
|
1725
|
+
route: handler.route.replace("/_scripts", scriptsPrefix),
|
|
1726
|
+
handler: handler.handler,
|
|
1727
|
+
middleware: handler.middleware
|
|
1728
|
+
});
|
|
1729
|
+
}
|
|
1730
|
+
if (script.registryKey === "gravatar") {
|
|
1731
|
+
const gravatarConfig = config.registry?.gravatar?.[0] || {};
|
|
1732
|
+
nuxt.options.runtimeConfig.public["nuxt-scripts"] = defu(
|
|
1733
|
+
{ gravatarProxy: { cacheMaxAge: gravatarConfig.cacheMaxAge ?? 3600 } },
|
|
1734
|
+
nuxt.options.runtimeConfig.public["nuxt-scripts"]
|
|
1735
|
+
);
|
|
1736
|
+
}
|
|
1737
|
+
if (script.registryKey === "googleMaps") {
|
|
1738
|
+
nuxt.options.runtimeConfig["nuxt-scripts"] = defu(
|
|
1739
|
+
{ googleMapsGeocodeProxy: { apiKey: nuxt.options.runtimeConfig.public.scripts?.googleMaps?.apiKey } },
|
|
1740
|
+
nuxt.options.runtimeConfig["nuxt-scripts"]
|
|
1741
|
+
);
|
|
1742
|
+
}
|
|
1563
1743
|
}
|
|
1744
|
+
nuxt.options.runtimeConfig.public["nuxt-scripts"] = defu(
|
|
1745
|
+
{ endpoints: enabledEndpoints },
|
|
1746
|
+
nuxt.options.runtimeConfig.public["nuxt-scripts"]
|
|
1747
|
+
);
|
|
1564
1748
|
}
|
|
1565
1749
|
});
|
|
1566
1750
|
|
|
1567
|
-
export { module$1 as default };
|
|
1751
|
+
export { applyAutoInject, module$1 as default, isProxyDisabled };
|