@nuxt/scripts 1.0.0-beta.7 → 1.0.0-rc.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (300) hide show
  1. package/bin/cli.mjs +2 -0
  2. package/dist/cli.d.mts +2 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.mjs +50 -0
  5. package/dist/devtools-client/200.html +1 -0
  6. package/dist/devtools-client/404.html +1 -0
  7. package/dist/devtools-client/_fonts/4ppnHhMi-pBsWSPo7mY0avYxlDoAg1N3PTzCwXLZ5rA-d9oibkGnTd1JL3tc_xnaVgBLYmOB8kjrK2cvZaqwj9s.woff2 +0 -0
  8. package/dist/devtools-client/_fonts/4qBuU9MRVUlPZNPSF7Xom_sK8RBEnfYu-9VXFrdq8A8-8TDwLE1HAj1sQn7XxVWtM_7sIaPM-DTdO3Pf8U2DF1U.woff2 +0 -0
  9. package/dist/devtools-client/_fonts/6dYsbWUd_BpKJ7mdDihgOcya1gHXLpJBuMYXux3WMjE-q3fYNS8YbW5n7ZeXI2vSNgkRWW5VDPKAl51SNTjG2qk.woff2 +0 -0
  10. package/dist/devtools-client/_fonts/Lr-hqqZZsYmCt0ITUlr1CUrWim9fsKvoDFZliMxgNHY-iTa_Yt_PzhOY9TX7ZXdSlEPim6iRt92xhECwaxWxd5w.woff2 +0 -0
  11. package/dist/devtools-client/_fonts/OknHvWI6KtYn1JQBzX7eSpNDBQ8520F9TvSUJYkVf6A-xeZn9253svK_8Q2LD0XEruY_MnEsuCRO5LenPoggC0Y.woff2 +0 -0
  12. package/dist/devtools-client/_fonts/PV2hrQG6wq5BlIPDjdL1IcOflycaghyt5MHzlBqZtlo-lb_WexLz3VZqfTN0oi554iBH5tT2j2UFEV-XErCAS3E.woff2 +0 -0
  13. package/dist/devtools-client/_fonts/UA7OtwYHwGN_HjcVGTdmiQxUit7FlqkCwxVUWSeXVnQ-B4OXCFOL_tWrYODpQTc07aMaj0c2cewTOmBRWR9tD-A.woff2 +0 -0
  14. package/dist/devtools-client/_fonts/VE4cDVCv5MxbFM7ZLoLCGbIpNd71zhp7MDI9lmN5Y7I-xZyDYCUVrd6LV8eVGF3Um3UZjBFuUtDGtvdyTBBRYBo.woff2 +0 -0
  15. package/dist/devtools-client/_fonts/fVoGbnMbBFd5L9BBp9fUPavUSkZ_EmsQNSyadkT-108-U4T0khaeLQSIhtt9eVvaCEKJjtWJ4ioRJOf8hvqkWY0.woff2 +0 -0
  16. package/dist/devtools-client/_fonts/lQAxeCEs1R0Lw-H9XRU1RlOARQN8J6npRsPjyEDMe5s-_DUSLEkO3tKTuun_gSnDLoQPVEnpOnyqZMOw0ByZ6PA.woff2 +0 -0
  17. package/dist/devtools-client/_fonts/lntlqNHKLV2n82yTwMde70QqOjcfLE2XJ5oKZ3vRPWc-z6TxpIZQdWXztWLr9_OFWqt_WJJoeGtuK_-XQMZGQwE.woff2 +0 -0
  18. package/dist/devtools-client/_fonts/qxAYvKsXWeYv731eb-h5TRurcdIP_W44mpNdX-HABAk-zUDeMEFlNtNbrwvT9JxLEBg0TphGy70O6RfIoIX_ZwU.woff2 +0 -0
  19. package/dist/devtools-client/_nuxt/B8PEiB0p.js +1 -0
  20. package/dist/devtools-client/_nuxt/BgPDxVUn.js +1 -0
  21. package/dist/devtools-client/_nuxt/BmlapxLP.js +1 -0
  22. package/dist/devtools-client/_nuxt/CM2vefXI.js +188 -0
  23. package/dist/devtools-client/_nuxt/DAF5Qk9P.js +1 -0
  24. package/dist/devtools-client/_nuxt/Dx6HhVmj.js +1 -0
  25. package/dist/devtools-client/_nuxt/S8LiR9M1.js +1 -0
  26. package/dist/devtools-client/_nuxt/builds/latest.json +1 -0
  27. package/dist/devtools-client/_nuxt/builds/meta/5458a3f2-af35-479c-8852-bf6f92fed611.json +1 -0
  28. package/dist/devtools-client/_nuxt/entry.BKkVrcJj.css +1 -0
  29. package/dist/devtools-client/_nuxt/error-404.d44aGwWI.css +1 -0
  30. package/dist/devtools-client/_nuxt/error-500.NthMfIEt.css +1 -0
  31. package/dist/devtools-client/_nuxt/first-party.C8Ha4JLM.css +1 -0
  32. package/dist/devtools-client/_nuxt/index.DZD1lwyI.css +1 -0
  33. package/dist/devtools-client/_nuxt/registry.B9lnjF_b.css +1 -0
  34. package/dist/devtools-client/_nuxt/vBkR1GJq.js +1 -0
  35. package/dist/devtools-client/_nuxt/wDzz0qaB.js +1 -0
  36. package/dist/devtools-client/docs/index.html +1 -0
  37. package/dist/devtools-client/first-party/index.html +1 -0
  38. package/dist/devtools-client/index.html +1 -0
  39. package/dist/devtools-client/registry/index.html +1 -0
  40. package/dist/module.d.mts +89 -80
  41. package/dist/module.d.ts +185 -0
  42. package/dist/module.json +1 -1
  43. package/dist/module.mjs +1056 -756
  44. package/dist/registry.d.mts +92 -4
  45. package/dist/registry.d.ts +94 -0
  46. package/dist/registry.mjs +668 -326
  47. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.d.vue.ts +77 -165
  48. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue +148 -227
  49. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue.d.ts +77 -165
  50. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.d.vue.ts +6 -55
  51. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.vue +12 -83
  52. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.vue.d.ts +6 -55
  53. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsCircle.d.vue.ts +5 -1
  54. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsCircle.vue +24 -38
  55. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsCircle.vue.d.ts +5 -1
  56. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsGeoJson.d.vue.ts +43 -0
  57. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsGeoJson.vue +60 -0
  58. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsGeoJson.vue.d.ts +43 -0
  59. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsHeatmapLayer.d.vue.ts +4 -0
  60. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsHeatmapLayer.vue +22 -26
  61. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsHeatmapLayer.vue.d.ts +4 -0
  62. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.d.vue.ts +11 -8
  63. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.vue +57 -57
  64. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.vue.d.ts +11 -8
  65. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.d.vue.ts +24 -42
  66. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue +71 -74
  67. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue.d.ts +24 -42
  68. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.d.vue.ts +19 -20
  69. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue +85 -38
  70. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue.d.ts +19 -20
  71. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.d.vue.ts +98 -0
  72. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.vue +263 -0
  73. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.vue.d.ts +98 -0
  74. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.d.vue.ts +10 -3
  75. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.vue +9 -41
  76. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.vue.d.ts +10 -3
  77. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolygon.d.vue.ts +7 -3
  78. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolygon.vue +23 -38
  79. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolygon.vue.d.ts +7 -3
  80. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolyline.d.vue.ts +7 -3
  81. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolyline.vue +23 -38
  82. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolyline.vue.d.ts +7 -3
  83. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsRectangle.d.vue.ts +7 -3
  84. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsRectangle.vue +24 -38
  85. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsRectangle.vue.d.ts +7 -3
  86. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsStaticMap.d.vue.ts +200 -0
  87. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsStaticMap.vue +170 -0
  88. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsStaticMap.vue.d.ts +200 -0
  89. package/dist/runtime/components/GoogleMaps/bindGoogleMapsEvents.d.ts +13 -0
  90. package/dist/runtime/components/GoogleMaps/bindGoogleMapsEvents.js +8 -0
  91. package/dist/runtime/components/GoogleMaps/injectionKeys.d.ts +10 -0
  92. package/dist/runtime/components/GoogleMaps/injectionKeys.js +2 -0
  93. package/dist/runtime/components/GoogleMaps/types.d.ts +42 -0
  94. package/dist/runtime/components/GoogleMaps/types.js +1 -0
  95. package/dist/runtime/components/GoogleMaps/useGoogleMapsResource.d.ts +98 -0
  96. package/dist/runtime/components/GoogleMaps/useGoogleMapsResource.js +126 -0
  97. package/dist/runtime/components/ScriptBlueskyEmbed.d.vue.ts +83 -0
  98. package/dist/runtime/components/ScriptBlueskyEmbed.vue +91 -0
  99. package/dist/runtime/components/ScriptBlueskyEmbed.vue.d.ts +83 -0
  100. package/dist/runtime/components/ScriptCarbonAds.d.vue.ts +4 -7
  101. package/dist/runtime/components/ScriptCarbonAds.vue +1 -0
  102. package/dist/runtime/components/ScriptCarbonAds.vue.d.ts +4 -7
  103. package/dist/runtime/components/ScriptCrisp.d.vue.ts +7 -11
  104. package/dist/runtime/components/ScriptCrisp.vue +2 -1
  105. package/dist/runtime/components/ScriptCrisp.vue.d.ts +7 -11
  106. package/dist/runtime/components/ScriptGoogleAdsense.d.vue.ts +4 -7
  107. package/dist/runtime/components/ScriptGoogleAdsense.vue +2 -1
  108. package/dist/runtime/components/ScriptGoogleAdsense.vue.d.ts +4 -7
  109. package/dist/runtime/components/ScriptGravatar.d.vue.ts +22 -0
  110. package/dist/runtime/components/ScriptGravatar.vue +46 -0
  111. package/dist/runtime/components/ScriptGravatar.vue.d.ts +22 -0
  112. package/dist/runtime/components/ScriptInstagramEmbed.d.vue.ts +12 -15
  113. package/dist/runtime/components/ScriptInstagramEmbed.vue +11 -3
  114. package/dist/runtime/components/ScriptInstagramEmbed.vue.d.ts +12 -15
  115. package/dist/runtime/components/ScriptIntercom.d.vue.ts +7 -11
  116. package/dist/runtime/components/ScriptIntercom.vue +5 -3
  117. package/dist/runtime/components/ScriptIntercom.vue.d.ts +7 -11
  118. package/dist/runtime/components/ScriptLemonSqueezy.d.vue.ts +2 -3
  119. package/dist/runtime/components/ScriptLemonSqueezy.vue +1 -0
  120. package/dist/runtime/components/ScriptLemonSqueezy.vue.d.ts +2 -3
  121. package/dist/runtime/components/ScriptPayPalButtons.d.vue.ts +43 -37
  122. package/dist/runtime/components/ScriptPayPalButtons.vue +49 -79
  123. package/dist/runtime/components/ScriptPayPalButtons.vue.d.ts +43 -37
  124. package/dist/runtime/components/ScriptPayPalMessages.d.vue.ts +37 -28
  125. package/dist/runtime/components/ScriptPayPalMessages.vue +47 -50
  126. package/dist/runtime/components/ScriptPayPalMessages.vue.d.ts +37 -28
  127. package/dist/runtime/components/ScriptStripePricingTable.d.vue.ts +5 -9
  128. package/dist/runtime/components/ScriptStripePricingTable.vue +3 -2
  129. package/dist/runtime/components/ScriptStripePricingTable.vue.d.ts +5 -9
  130. package/dist/runtime/components/ScriptVimeoPlayer.d.vue.ts +17 -11
  131. package/dist/runtime/components/ScriptVimeoPlayer.vue +14 -10
  132. package/dist/runtime/components/ScriptVimeoPlayer.vue.d.ts +17 -11
  133. package/dist/runtime/components/ScriptXEmbed.d.vue.ts +10 -14
  134. package/dist/runtime/components/ScriptXEmbed.vue +21 -12
  135. package/dist/runtime/components/ScriptXEmbed.vue.d.ts +10 -14
  136. package/dist/runtime/components/ScriptYouTubePlayer.d.vue.ts +10 -15
  137. package/dist/runtime/components/ScriptYouTubePlayer.vue +12 -5
  138. package/dist/runtime/components/ScriptYouTubePlayer.vue.d.ts +10 -15
  139. package/dist/runtime/composables/useScript.js +159 -8
  140. package/dist/runtime/composables/useScriptEventPage.js +2 -2
  141. package/dist/runtime/composables/useScriptProxyToken.d.ts +12 -0
  142. package/dist/runtime/composables/useScriptProxyToken.js +4 -0
  143. package/dist/runtime/composables/useScriptProxyUrl.d.ts +12 -0
  144. package/dist/runtime/composables/useScriptProxyUrl.js +27 -0
  145. package/dist/runtime/composables/useScriptTriggerConsent.d.ts +10 -0
  146. package/dist/runtime/composables/useScriptTriggerConsent.js +33 -20
  147. package/dist/runtime/composables/useScriptTriggerElement.js +1 -1
  148. package/dist/runtime/composables/useScriptTriggerIdleTimeout.js +1 -1
  149. package/dist/runtime/devtools-standalone-bridge.client.d.ts +8 -0
  150. package/dist/runtime/devtools-standalone-bridge.client.js +50 -0
  151. package/dist/runtime/plugins/proxy-token.server.d.ts +10 -0
  152. package/dist/runtime/plugins/proxy-token.server.js +17 -0
  153. package/dist/runtime/registry/bing-uet.d.ts +198 -0
  154. package/dist/runtime/registry/bing-uet.js +43 -0
  155. package/dist/runtime/registry/bluesky-embed.d.ts +112 -0
  156. package/dist/runtime/registry/bluesky-embed.js +68 -0
  157. package/dist/runtime/registry/clarity.d.ts +16 -17
  158. package/dist/runtime/registry/clarity.js +33 -31
  159. package/dist/runtime/registry/cloudflare-web-analytics.d.ts +2 -13
  160. package/dist/runtime/registry/cloudflare-web-analytics.js +2 -14
  161. package/dist/runtime/registry/crisp.d.ts +10 -40
  162. package/dist/runtime/registry/crisp.js +2 -33
  163. package/dist/runtime/registry/databuddy-analytics.d.ts +2 -35
  164. package/dist/runtime/registry/databuddy-analytics.js +20 -45
  165. package/dist/runtime/registry/fathom-analytics.d.ts +7 -26
  166. package/dist/runtime/registry/fathom-analytics.js +3 -25
  167. package/dist/runtime/registry/google-adsense.d.ts +3 -11
  168. package/dist/runtime/registry/google-adsense.js +2 -11
  169. package/dist/runtime/registry/google-analytics.d.ts +9 -7
  170. package/dist/runtime/registry/google-analytics.js +15 -9
  171. package/dist/runtime/registry/google-maps.d.ts +3 -9
  172. package/dist/runtime/registry/google-maps.js +2 -8
  173. package/dist/runtime/registry/google-recaptcha.d.ts +2 -6
  174. package/dist/runtime/registry/google-recaptcha.js +4 -12
  175. package/dist/runtime/registry/google-sign-in.d.ts +2 -13
  176. package/dist/runtime/registry/google-sign-in.js +2 -22
  177. package/dist/runtime/registry/google-tag-manager.d.ts +8 -29
  178. package/dist/runtime/registry/google-tag-manager.js +14 -28
  179. package/dist/runtime/registry/gravatar.d.ts +26 -0
  180. package/dist/runtime/registry/gravatar.js +33 -0
  181. package/dist/runtime/registry/hotjar.d.ts +4 -6
  182. package/dist/runtime/registry/hotjar.js +2 -5
  183. package/dist/runtime/registry/instagram-embed.d.ts +3 -18
  184. package/dist/runtime/registry/instagram-embed.js +4 -19
  185. package/dist/runtime/registry/intercom.d.ts +5 -13
  186. package/dist/runtime/registry/intercom.js +2 -12
  187. package/dist/runtime/registry/matomo-analytics.d.ts +12 -15
  188. package/dist/runtime/registry/matomo-analytics.js +31 -13
  189. package/dist/runtime/registry/meta-pixel.d.ts +12 -8
  190. package/dist/runtime/registry/meta-pixel.js +12 -5
  191. package/dist/runtime/registry/mixpanel-analytics.d.ts +32 -0
  192. package/dist/runtime/registry/mixpanel-analytics.js +58 -0
  193. package/dist/runtime/registry/npm.d.ts +3 -7
  194. package/dist/runtime/registry/npm.js +2 -9
  195. package/dist/runtime/registry/paypal.d.ts +4 -25
  196. package/dist/runtime/registry/paypal.js +3 -66
  197. package/dist/runtime/registry/plausible-analytics.js +19 -14
  198. package/dist/runtime/registry/posthog.d.ts +18 -14
  199. package/dist/runtime/registry/posthog.js +18 -16
  200. package/dist/runtime/registry/reddit-pixel.d.ts +5 -6
  201. package/dist/runtime/registry/reddit-pixel.js +2 -4
  202. package/dist/runtime/registry/rybbit-analytics.d.ts +2 -14
  203. package/dist/runtime/registry/rybbit-analytics.js +10 -20
  204. package/dist/runtime/registry/schemas.d.ts +1047 -0
  205. package/dist/runtime/registry/schemas.js +1004 -0
  206. package/dist/runtime/registry/segment.d.ts +2 -5
  207. package/dist/runtime/registry/segment.js +2 -5
  208. package/dist/runtime/registry/snapchat-pixel.d.ts +5 -34
  209. package/dist/runtime/registry/snapchat-pixel.js +2 -20
  210. package/dist/runtime/registry/stripe.d.ts +3 -4
  211. package/dist/runtime/registry/stripe.js +2 -4
  212. package/dist/runtime/registry/tiktok-pixel.d.ts +20 -9
  213. package/dist/runtime/registry/tiktok-pixel.js +24 -7
  214. package/dist/runtime/registry/umami-analytics.d.ts +2 -31
  215. package/dist/runtime/registry/umami-analytics.js +2 -36
  216. package/dist/runtime/registry/vercel-analytics.d.ts +29 -0
  217. package/dist/runtime/registry/vercel-analytics.js +84 -0
  218. package/dist/runtime/registry/vimeo-player.d.ts +2 -2
  219. package/dist/runtime/registry/vimeo-player.js +1 -1
  220. package/dist/runtime/registry/x-embed.d.ts +3 -21
  221. package/dist/runtime/registry/x-embed.js +2 -21
  222. package/dist/runtime/registry/x-pixel.d.ts +4 -7
  223. package/dist/runtime/registry/x-pixel.js +2 -5
  224. package/dist/runtime/registry/youtube-player.d.ts +7 -7
  225. package/dist/runtime/registry/youtube-player.js +1 -1
  226. package/dist/runtime/server/bluesky-embed-image.d.ts +2 -0
  227. package/dist/runtime/server/bluesky-embed-image.js +7 -0
  228. package/dist/runtime/server/bluesky-embed.d.ts +2 -0
  229. package/dist/runtime/server/bluesky-embed.js +78 -0
  230. package/dist/runtime/server/google-maps-geocode-proxy.d.ts +2 -0
  231. package/dist/runtime/server/google-maps-geocode-proxy.js +38 -0
  232. package/dist/runtime/server/google-static-maps-proxy.d.ts +1 -1
  233. package/dist/runtime/server/google-static-maps-proxy.js +18 -23
  234. package/dist/runtime/server/gravatar-proxy.d.ts +2 -0
  235. package/dist/runtime/server/gravatar-proxy.js +46 -0
  236. package/dist/runtime/server/instagram-embed-asset.d.ts +1 -1
  237. package/dist/runtime/server/instagram-embed-asset.js +8 -41
  238. package/dist/runtime/server/instagram-embed-image.d.ts +1 -1
  239. package/dist/runtime/server/instagram-embed-image.js +6 -53
  240. package/dist/runtime/server/instagram-embed.d.ts +1 -0
  241. package/dist/runtime/server/instagram-embed.js +82 -40
  242. package/dist/runtime/server/proxy-handler.js +102 -85
  243. package/dist/runtime/server/utils/cached-upstream.d.ts +55 -0
  244. package/dist/runtime/server/utils/cached-upstream.js +65 -0
  245. package/dist/runtime/server/utils/embed-rewriters.d.ts +19 -0
  246. package/dist/runtime/server/utils/embed-rewriters.js +41 -0
  247. package/dist/runtime/server/utils/image-proxy.d.ts +14 -0
  248. package/dist/runtime/server/utils/image-proxy.js +73 -0
  249. package/dist/runtime/server/utils/instagram-embed.d.ts +16 -0
  250. package/dist/runtime/server/utils/instagram-embed.js +153 -0
  251. package/dist/runtime/server/utils/privacy.d.ts +1 -10
  252. package/dist/runtime/server/utils/privacy.js +60 -40
  253. package/dist/runtime/server/utils/proxy-url.d.ts +9 -0
  254. package/dist/runtime/server/utils/proxy-url.js +21 -0
  255. package/dist/runtime/server/utils/sign-constants.d.ts +16 -0
  256. package/dist/runtime/server/utils/sign-constants.js +5 -0
  257. package/dist/runtime/server/utils/sign.d.ts +101 -0
  258. package/dist/runtime/server/utils/sign.js +91 -0
  259. package/dist/runtime/server/utils/withSigning.d.ts +23 -0
  260. package/dist/runtime/server/utils/withSigning.js +19 -0
  261. package/dist/runtime/server/x-embed-image.d.ts +1 -1
  262. package/dist/runtime/server/x-embed-image.js +5 -49
  263. package/dist/runtime/server/x-embed.js +26 -6
  264. package/dist/runtime/types.d.ts +311 -55
  265. package/dist/runtime/types.js +1 -2
  266. package/dist/runtime/utils/pure.d.ts +1 -1
  267. package/dist/runtime/utils.d.ts +6 -4
  268. package/dist/runtime/utils.js +31 -14
  269. package/dist/stats.d.mts +202 -0
  270. package/dist/stats.d.ts +202 -0
  271. package/dist/stats.mjs +3835 -0
  272. package/dist/types-source.d.mts +17 -0
  273. package/dist/types-source.d.ts +17 -0
  274. package/dist/types-source.mjs +3787 -0
  275. package/dist/types.d.mts +4 -2
  276. package/package.json +41 -63
  277. package/README.md +0 -86
  278. package/dist/client/200.html +0 -1
  279. package/dist/client/404.html +0 -1
  280. package/dist/client/_nuxt/BJa0m50V.js +0 -1
  281. package/dist/client/_nuxt/BPQ3VLAy.js +0 -1
  282. package/dist/client/_nuxt/Ci5iXYuB.js +0 -1
  283. package/dist/client/_nuxt/DaI2y8Uz.js +0 -162
  284. package/dist/client/_nuxt/builds/latest.json +0 -1
  285. package/dist/client/_nuxt/builds/meta/9b4fb16a-3c62-48b0-8295-126cb077b5d3.json +0 -1
  286. package/dist/client/_nuxt/entry.D45OuV0w.css +0 -1
  287. package/dist/client/_nuxt/error-404.B57D-jUQ.css +0 -1
  288. package/dist/client/_nuxt/error-500.DTHUW7BI.css +0 -1
  289. package/dist/client/_nuxt/vPLZfVXe.js +0 -1
  290. package/dist/client/index.html +0 -1
  291. package/dist/runtime/components/ScriptPayPalMarks.d.vue.ts +0 -52
  292. package/dist/runtime/components/ScriptPayPalMarks.vue +0 -69
  293. package/dist/runtime/components/ScriptPayPalMarks.vue.d.ts +0 -52
  294. package/dist/runtime/validation/mock.d.ts +0 -42
  295. package/dist/runtime/validation/mock.js +0 -21
  296. package/dist/runtime/validation/valibot.d.ts +0 -1
  297. package/dist/runtime/validation/valibot.js +0 -1
  298. /package/dist/{client → devtools-client}/_nuxt/CVO1_9PV.js +0 -0
  299. /package/dist/{client → devtools-client}/_nuxt/Cp-IABpG.js +0 -0
  300. /package/dist/{client → devtools-client}/_nuxt/D0r3Knsf.js +0 -0
@@ -0,0 +1,153 @@
1
+ import { buildProxyUrl } from "./proxy-url.js";
2
+ export const RSRC_RE = /url\(\/rsrc\.php([^)]+)\)/g;
3
+ export const AMP_RE = /&/g;
4
+ export const SCONTENT_RE = /https:\/\/scontent[^"'\s),]+\.cdninstagram\.com[^"'\s),]+/g;
5
+ export const STATIC_CDN_RE = /https:\/\/static\.cdninstagram\.com[^"'\s),]+/g;
6
+ export const LOOKASIDE_RE = /https:\/\/lookaside\.instagram\.com[^"'\s),]+/g;
7
+ export const INSTAGRAM_IMAGE_HOSTS = ["scontent.cdninstagram.com", "lookaside.instagram.com"];
8
+ export const INSTAGRAM_ASSET_HOST = "static.cdninstagram.com";
9
+ const CHARSET_RE = /@charset\s[^;]+;/gi;
10
+ const IMPORT_RE = /@import\s[^;]+;/gi;
11
+ const WHITESPACE_RE = /\s/;
12
+ const AT_RULE_NAME_RE = /@([\w-]+)/;
13
+ const MULTI_SPACE_RE = /\s+/g;
14
+ export function proxyImageUrl(url, prefix = "/_scripts", secret) {
15
+ return buildProxyUrl(`${prefix}/embed/instagram-image`, { url: url.replace(AMP_RE, "&") }, secret);
16
+ }
17
+ export function proxyAssetUrl(url, prefix = "/_scripts", secret) {
18
+ return buildProxyUrl(`${prefix}/embed/instagram-asset`, { url: url.replace(AMP_RE, "&") }, secret);
19
+ }
20
+ export function rewriteUrl(url, prefix = "/_scripts", secret) {
21
+ try {
22
+ const parsed = new URL(url);
23
+ if (parsed.hostname === INSTAGRAM_ASSET_HOST)
24
+ return proxyAssetUrl(url, prefix, secret);
25
+ if (INSTAGRAM_IMAGE_HOSTS.some((h) => parsed.hostname === h || parsed.hostname.endsWith(`.cdninstagram.com`)))
26
+ return proxyImageUrl(url, prefix, secret);
27
+ } catch {
28
+ }
29
+ return url;
30
+ }
31
+ export function rewriteUrlsInText(text, prefix = "/_scripts", secret) {
32
+ return text.replace(SCONTENT_RE, (m) => proxyImageUrl(m, prefix, secret)).replace(STATIC_CDN_RE, (m) => proxyAssetUrl(m, prefix, secret)).replace(LOOKASIDE_RE, (m) => proxyImageUrl(m, prefix, secret));
33
+ }
34
+ export function scopeCss(css, scopeSelector) {
35
+ let result = css.replace(CHARSET_RE, "");
36
+ result = result.replace(IMPORT_RE, "");
37
+ return processRules(result, scopeSelector);
38
+ }
39
+ function processRules(css, scopeSelector) {
40
+ const output = [];
41
+ let i = 0;
42
+ while (i < css.length) {
43
+ while (i < css.length && WHITESPACE_RE.test(css[i])) i++;
44
+ if (i >= css.length)
45
+ break;
46
+ if (css[i] === "@") {
47
+ const atRule = extractAtRule(css, i);
48
+ if (atRule) {
49
+ const atName = atRule.content.match(AT_RULE_NAME_RE)?.[1]?.toLowerCase();
50
+ if (atName === "media" || atName === "supports" || atName === "layer") {
51
+ const braceStart = atRule.content.indexOf("{");
52
+ if (braceStart === -1) {
53
+ output.push(atRule.content);
54
+ } else {
55
+ const innerCss = atRule.content.slice(braceStart + 1, -1);
56
+ const scopedInner = processRules(innerCss, scopeSelector);
57
+ output.push(`${atRule.content.slice(0, braceStart + 1)}${scopedInner}}`);
58
+ }
59
+ } else if (atName === "keyframes" || atName === "-webkit-keyframes" || atName === "font-face") {
60
+ output.push(atRule.content);
61
+ }
62
+ i = atRule.end;
63
+ continue;
64
+ }
65
+ }
66
+ const bracePos = css.indexOf("{", i);
67
+ if (bracePos === -1)
68
+ break;
69
+ const selector = css.slice(i, bracePos).trim();
70
+ const block = extractBlock(css, bracePos);
71
+ if (!block)
72
+ break;
73
+ i = block.end;
74
+ if (!selector)
75
+ continue;
76
+ const selectors = splitTopLevel(selector, ",").map((s) => s.trim());
77
+ const filteredSelectors = selectors.filter((s) => {
78
+ const normalized = s.replace(MULTI_SPACE_RE, " ").trim().toLowerCase();
79
+ return normalized !== ":root" && normalized !== "html" && normalized !== "body" && !normalized.startsWith(":root ") && !normalized.startsWith("html ") && !normalized.startsWith("body ") && normalized !== "html, body";
80
+ });
81
+ if (filteredSelectors.length === 0)
82
+ continue;
83
+ const scopedSelectors = filteredSelectors.map((s) => `${scopeSelector} ${s}`);
84
+ output.push(`${scopedSelectors.join(", ")} ${block.content}`);
85
+ }
86
+ return output.join("\n");
87
+ }
88
+ function extractAtRule(css, start) {
89
+ const bracePos = css.indexOf("{", start);
90
+ const semiPos = css.indexOf(";", start);
91
+ if (semiPos !== -1 && (bracePos === -1 || semiPos < bracePos)) {
92
+ return { content: css.slice(start, semiPos + 1), end: semiPos + 1 };
93
+ }
94
+ if (bracePos === -1)
95
+ return null;
96
+ const block = extractBlock(css, bracePos);
97
+ if (!block)
98
+ return null;
99
+ return {
100
+ content: css.slice(start, bracePos) + block.content,
101
+ end: block.end
102
+ };
103
+ }
104
+ function splitTopLevel(input, separator) {
105
+ const parts = [];
106
+ let depth = 0;
107
+ let quote = null;
108
+ let start = 0;
109
+ for (let i = 0; i < input.length; i++) {
110
+ const ch = input[i];
111
+ if (quote) {
112
+ if (ch === "\\") {
113
+ i++;
114
+ continue;
115
+ }
116
+ if (ch === quote)
117
+ quote = null;
118
+ continue;
119
+ }
120
+ if (ch === '"' || ch === "'") {
121
+ quote = ch;
122
+ continue;
123
+ }
124
+ if (ch === "(" || ch === "[") {
125
+ depth++;
126
+ continue;
127
+ }
128
+ if (ch === ")" || ch === "]") {
129
+ depth--;
130
+ continue;
131
+ }
132
+ if (ch === separator && depth === 0) {
133
+ parts.push(input.slice(start, i));
134
+ start = i + 1;
135
+ }
136
+ }
137
+ parts.push(input.slice(start));
138
+ return parts;
139
+ }
140
+ function extractBlock(css, openBrace) {
141
+ let depth = 0;
142
+ for (let j = openBrace; j < css.length; j++) {
143
+ if (css[j] === "{") {
144
+ depth++;
145
+ } else if (css[j] === "}") {
146
+ depth--;
147
+ if (depth === 0) {
148
+ return { content: css.slice(openBrace, j + 1), end: j + 1 };
149
+ }
150
+ }
151
+ }
152
+ return null;
153
+ }
@@ -20,7 +20,7 @@ export interface ProxyPrivacy {
20
20
  * Privacy input: `true` = full anonymize, `false` = passthrough (still strips sensitive headers),
21
21
  * or a `ProxyPrivacy` object for granular control (unset flags default to `false` — opt-in).
22
22
  */
23
- export type ProxyPrivacyInput = boolean | ProxyPrivacy | null;
23
+ export type ProxyPrivacyInput = boolean | ProxyPrivacy;
24
24
  /** Resolved privacy with all flags explicitly set. */
25
25
  export type ResolvedProxyPrivacy = Required<ProxyPrivacy>;
26
26
  /**
@@ -71,7 +71,6 @@ export declare const STRIP_PARAMS: {
71
71
  browserVersion: string[];
72
72
  browserData: string[];
73
73
  location: string[];
74
- canvas: string[];
75
74
  deviceInfo: string[];
76
75
  };
77
76
  /**
@@ -130,12 +129,4 @@ export declare function generalizeTimezone(value: unknown): string | number;
130
129
  * (timezone, language, screen dimensions) while keeping low-entropy values.
131
130
  */
132
131
  export declare function anonymizeDeviceInfo(value: string): string;
133
- /**
134
- * Recursively anonymize fingerprinting data in payload.
135
- * Fields are generalized or normalized rather than stripped, so endpoints
136
- * still receive valid data with reduced fingerprinting precision.
137
- *
138
- * When `privacy` is provided, only categories with their flag set to `true` are processed.
139
- * Default (no arg) = all categories active, so existing callers work unchanged.
140
- */
141
132
  export declare function stripPayloadFingerprinting(payload: Record<string, unknown>, privacy?: ResolvedProxyPrivacy): Record<string, unknown>;
@@ -1,8 +1,17 @@
1
1
  const FULL_PRIVACY = { ip: true, userAgent: true, language: true, screen: true, timezone: true, hardware: true };
2
2
  const NO_PRIVACY = { ip: false, userAgent: false, language: false, screen: false, timezone: false, hardware: false };
3
+ const MAJOR_VERSION_RE = /^(\d+)/;
4
+ const VERSION_RE = /^(\d+)(([.\-_])\d+)*/;
5
+ const VERSION_SPLIT_RE = /[.\-_]/;
6
+ const SNAPCHAT_VERSION_RE = /("version"\s*:\s*")(\d+(?:\.\d+)*)/g;
7
+ const GA_VERSION_RE = /;(\d+(?:\.\d+)*)/g;
8
+ const UPPERCASE_RE = /^[A-Z]/;
9
+ const LANG_CODE_RE = /^[a-z]{2}(?:-[a-z]{2,})?$/i;
3
10
  export function resolvePrivacy(input) {
4
- if (input === true) return { ...FULL_PRIVACY };
5
- if (input === false || input === void 0 || input === null) return { ...NO_PRIVACY };
11
+ if (input === true)
12
+ return { ...FULL_PRIVACY };
13
+ if (input === false || input === void 0)
14
+ return { ...NO_PRIVACY };
6
15
  return {
7
16
  ip: input.ip ?? false,
8
17
  userAgent: input.userAgent ?? false,
@@ -13,8 +22,10 @@ export function resolvePrivacy(input) {
13
22
  };
14
23
  }
15
24
  export function mergePrivacy(base, override) {
16
- if (override === void 0 || override === null) return base;
17
- if (typeof override === "boolean") return resolvePrivacy(override);
25
+ if (override === void 0)
26
+ return base;
27
+ if (typeof override === "boolean")
28
+ return resolvePrivacy(override);
18
29
  return {
19
30
  ip: override.ip !== void 0 ? override.ip : base.ip,
20
31
  userAgent: override.userAgent !== void 0 ? override.userAgent : base.userAgent,
@@ -67,11 +78,13 @@ export const STRIP_PARAMS = {
67
78
  // Browser version lists — generalized to major versions (d_bvs = Snapchat, uafvl = GA Client Hints)
68
79
  browserVersion: ["d_bvs", "uafvl"],
69
80
  // Browser data lists — replaced with empty value
70
- browserData: ["plugins", "fonts"],
81
+ browserData: ["plugins", "fonts", "audiofingerprint"],
71
82
  // Location/Timezone — generalized
72
83
  location: ["tz", "timezone", "timezoneoffset"],
73
- // Canvas/WebGL/Audio fingerprints — replaced with empty value (pure fingerprints, no analytics value)
74
- canvas: ["canvas", "webgl", "audiofingerprint"],
84
+ // Canvas/WebGL fingerprints — neutralized at build time via AST rewriting (rewrite-ast.ts).
85
+ // These params are no longer stripped at runtime; the source APIs (toDataURL, WEBGL_debug_renderer_info)
86
+ // are neutralized before the script ever runs.
87
+ // canvas: ['canvas', 'webgl'],
75
88
  // Combined device fingerprinting (X/Twitter dv param contains: timezone, locale, vendor, platform, screen, etc.)
76
89
  deviceInfo: ["dv", "device_info", "deviceinfo"]
77
90
  };
@@ -81,7 +94,7 @@ export const NORMALIZE_PARAMS = {
81
94
  };
82
95
  export function anonymizeIP(ip) {
83
96
  if (ip.includes(":")) {
84
- return ip.split(":").slice(0, 3).join(":") + "::";
97
+ return `${ip.split(":").slice(0, 3).join(":")}::`;
85
98
  }
86
99
  const parts = ip.split(".");
87
100
  if (parts.length === 4) {
@@ -103,7 +116,7 @@ export function normalizeUserAgent(ua) {
103
116
  const idx = ua.indexOf(pattern);
104
117
  if (idx !== -1) {
105
118
  const versionStart = idx + pattern.length;
106
- const majorVersion = ua.slice(versionStart).match(/^(\d+)/)?.[1];
119
+ const majorVersion = ua.slice(versionStart).match(MAJOR_VERSION_RE)?.[1];
107
120
  if (majorVersion)
108
121
  return `Mozilla/5.0 (compatible; ${family}/${majorVersion}.0)`;
109
122
  }
@@ -119,8 +132,10 @@ const SCREEN_BUCKETS = {
119
132
  mobile: { w: 360, h: 640 }
120
133
  };
121
134
  function getDeviceClass(width) {
122
- if (width >= 1200) return "desktop";
123
- if (width >= 700) return "tablet";
135
+ if (width >= 1200)
136
+ return "desktop";
137
+ if (width >= 700)
138
+ return "tablet";
124
139
  return "mobile";
125
140
  }
126
141
  export function generalizeScreen(value, dimension) {
@@ -139,31 +154,38 @@ export function generalizeScreen(value, dimension) {
139
154
  }
140
155
  export function generalizeHardware(value) {
141
156
  const num = typeof value === "number" ? value : Number(value);
142
- if (Number.isNaN(num)) return 4;
143
- if (num >= 16) return 16;
144
- if (num >= 8) return 8;
145
- if (num >= 4) return 4;
157
+ if (Number.isNaN(num))
158
+ return 4;
159
+ if (num >= 16)
160
+ return 16;
161
+ if (num >= 8)
162
+ return 8;
163
+ if (num >= 4)
164
+ return 4;
146
165
  return 2;
147
166
  }
148
167
  export function generalizeVersion(value) {
149
- if (typeof value !== "string") return String(value);
150
- const match = value.match(/^(\d+)(([.\-_])\d+)*/);
151
- if (!match) return String(value);
168
+ if (typeof value !== "string")
169
+ return String(value);
170
+ const match = value.match(VERSION_RE);
171
+ if (!match)
172
+ return String(value);
152
173
  const major = match[1];
153
174
  const sep = match[3] || ".";
154
- const segmentCount = value.split(/[.\-_]/).length;
155
- return major + (sep + "0").repeat(segmentCount - 1);
175
+ const segmentCount = value.split(VERSION_SPLIT_RE).length;
176
+ return major + `${sep}0`.repeat(segmentCount - 1);
156
177
  }
157
178
  export function generalizeBrowserVersions(value) {
158
- if (typeof value !== "string") return String(value);
179
+ if (typeof value !== "string")
180
+ return String(value);
159
181
  const zeroSegments = (ver) => {
160
182
  const parts = ver.split(".");
161
183
  return parts[0] + parts.slice(1).map(() => ".0").join("");
162
184
  };
163
185
  if (value.includes('"version"'))
164
- return value.replace(/("version"\s*:\s*")(\d+(?:\.\d+)*)/g, (_, prefix, ver) => prefix + zeroSegments(ver));
186
+ return value.replace(SNAPCHAT_VERSION_RE, (_, prefix, ver) => prefix + zeroSegments(ver));
165
187
  if (value.includes(";"))
166
- return value.replace(/;(\d+(?:\.\d+)*)/g, (_, ver) => ";" + zeroSegments(ver));
188
+ return value.replace(GA_VERSION_RE, (_, ver) => `;${zeroSegments(ver)}`);
167
189
  return value;
168
190
  }
169
191
  export function generalizeTimezone(value) {
@@ -178,15 +200,16 @@ export function generalizeTimezone(value) {
178
200
  export function anonymizeDeviceInfo(value) {
179
201
  const sep = value.includes("|") ? "|" : "&";
180
202
  const parts = value.split(sep);
181
- if (parts.length < 4) return value;
203
+ if (parts.length < 4)
204
+ return value;
182
205
  const result = [...parts];
183
206
  for (let i = 0; i < parts.length; i++) {
184
207
  const part = parts[i];
185
- if (part.includes("/") && /^[A-Z]/.test(part)) {
208
+ if (part.includes("/") && UPPERCASE_RE.test(part)) {
186
209
  result[i] = String(generalizeTimezone(part));
187
210
  continue;
188
211
  }
189
- if (/^[a-z]{2}(?:-[a-z]{2,})?$/i.test(part)) {
212
+ if (LANG_CODE_RE.test(part)) {
190
213
  result[i] = normalizeLanguage(part);
191
214
  continue;
192
215
  }
@@ -209,6 +232,13 @@ export function anonymizeDeviceInfo(value) {
209
232
  }
210
233
  return result.join(sep);
211
234
  }
235
+ function matchesParam(key, params) {
236
+ const lk = key.toLowerCase();
237
+ return params.some((pm) => {
238
+ const lp = pm.toLowerCase();
239
+ return lk === lp || lk.startsWith(`${lp}[`);
240
+ });
241
+ }
212
242
  export function stripPayloadFingerprinting(payload, privacy) {
213
243
  const p = privacy || FULL_PRIVACY;
214
244
  const result = {};
@@ -216,18 +246,12 @@ export function stripPayloadFingerprinting(payload, privacy) {
216
246
  for (const [key, value] of Object.entries(payload)) {
217
247
  if (key.toLowerCase() === "sw") {
218
248
  const num = typeof value === "number" ? value : Number(value);
219
- if (!Number.isNaN(num)) deviceClass = getDeviceClass(num);
249
+ if (!Number.isNaN(num))
250
+ deviceClass = getDeviceClass(num);
220
251
  }
221
252
  }
222
253
  for (const [key, value] of Object.entries(payload)) {
223
254
  const lowerKey = key.toLowerCase();
224
- const matchesParam = (key2, params) => {
225
- const lk = key2.toLowerCase();
226
- return params.some((pm) => {
227
- const lp = pm.toLowerCase();
228
- return lk === lp || lk.startsWith(lp + "[");
229
- });
230
- };
231
255
  const isLanguageParam = NORMALIZE_PARAMS.language.some((pm) => lowerKey === pm.toLowerCase());
232
256
  if (isLanguageParam) {
233
257
  if (Array.isArray(value)) {
@@ -264,7 +288,7 @@ export function stripPayloadFingerprinting(payload, privacy) {
264
288
  continue;
265
289
  }
266
290
  if (matchesParam(key, STRIP_PARAMS.hardware)) {
267
- result[key] = p.screen ? generalizeHardware(value) : value;
291
+ result[key] = p.hardware ? generalizeHardware(value) : value;
268
292
  continue;
269
293
  }
270
294
  if (matchesParam(key, STRIP_PARAMS.version)) {
@@ -280,11 +304,7 @@ export function stripPayloadFingerprinting(payload, privacy) {
280
304
  continue;
281
305
  }
282
306
  if (matchesParam(key, STRIP_PARAMS.browserData)) {
283
- result[key] = p.hardware ? Array.isArray(value) ? [] : "" : value;
284
- continue;
285
- }
286
- if (matchesParam(key, STRIP_PARAMS.canvas)) {
287
- result[key] = p.hardware ? typeof value === "number" ? 0 : typeof value === "object" ? {} : "" : value;
307
+ result[key] = p.hardware ? Array.isArray(value) ? [] : typeof value === "number" ? 0 : "" : value;
288
308
  continue;
289
309
  }
290
310
  if (matchesParam(key, STRIP_PARAMS.deviceInfo)) {
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Build a proxy URL with query params, signing it when a secret is available.
3
+ *
4
+ * Used by embed handlers that inject proxy URLs into HTML/JSON responses.
5
+ * When `secret` is set, URLs are HMAC-signed so clients can fetch them without
6
+ * needing a page token. When it's undefined, URLs fall back to unsigned form
7
+ * (which is only safe when the `withSigning` middleware has no secret either).
8
+ */
9
+ export declare function buildProxyUrl(path: string, query: Record<string, unknown>, secret?: string): string;
@@ -0,0 +1,21 @@
1
+ import { buildSignedProxyUrl } from "./sign.js";
2
+ export function buildProxyUrl(path, query, secret) {
3
+ if (secret)
4
+ return buildSignedProxyUrl(path, query, secret);
5
+ const parts = [];
6
+ for (const [key, value] of Object.entries(query)) {
7
+ if (value === void 0 || value === null)
8
+ continue;
9
+ const encodedKey = encodeURIComponent(key);
10
+ if (Array.isArray(value)) {
11
+ for (const item of value) {
12
+ if (item === void 0 || item === null)
13
+ continue;
14
+ parts.push(`${encodedKey}=${encodeURIComponent(String(item))}`);
15
+ }
16
+ } else {
17
+ parts.push(`${encodedKey}=${encodeURIComponent(String(value))}`);
18
+ }
19
+ }
20
+ return parts.length ? `${path}?${parts.join("&")}` : path;
21
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Signing constants shared between server (HMAC) and client (page-token) code.
3
+ *
4
+ * Kept in a crypto-free module so client bundles can import the param names
5
+ * without pulling in `node:crypto`.
6
+ */
7
+ /** Query param name for the HMAC signature. */
8
+ export declare const SIG_PARAM = "sig";
9
+ /** Length of the hex signature (16 chars = 64 bits). */
10
+ export declare const SIG_LENGTH = 16;
11
+ /** Query param name for the page token. */
12
+ export declare const PAGE_TOKEN_PARAM = "_pt";
13
+ /** Query param name for the page token timestamp. */
14
+ export declare const PAGE_TOKEN_TS_PARAM = "_ts";
15
+ /** Default max age for page tokens in seconds (1 hour). */
16
+ export declare const PAGE_TOKEN_MAX_AGE = 3600;
@@ -0,0 +1,5 @@
1
+ export const SIG_PARAM = "sig";
2
+ export const SIG_LENGTH = 16;
3
+ export const PAGE_TOKEN_PARAM = "_pt";
4
+ export const PAGE_TOKEN_TS_PARAM = "_ts";
5
+ export const PAGE_TOKEN_MAX_AGE = 3600;
@@ -0,0 +1,101 @@
1
+ /**
2
+ * HMAC URL signing for proxy endpoints.
3
+ *
4
+ * ## Why
5
+ *
6
+ * Proxy endpoints like `/_scripts/proxy/google-static-maps` inject a server-side
7
+ * API key and forward requests to third-party services. Without signing, anyone
8
+ * can call these endpoints with arbitrary parameters and burn the site owner's
9
+ * API quota. Signing ensures only URLs generated server-side (during SSR/prerender
10
+ * or via the `/_scripts/sign` endpoint) are accepted.
11
+ *
12
+ * ## How
13
+ *
14
+ * 1. The module stores a deterministic secret in `runtimeConfig.nuxt-scripts.proxySecret`
15
+ * (env: `NUXT_SCRIPTS_PROXY_SECRET`).
16
+ * 2. URLs are canonicalized (sort query keys, strip `sig`) and signed with HMAC-SHA256.
17
+ * 3. The first 16 hex chars (64 bits) of the digest is appended as `?sig=<hex>`.
18
+ * 4. Endpoints wrapped with `withSigning()` verify the sig against the current request.
19
+ *
20
+ * A 64-bit signature is enough to defeat brute force for this threat model
21
+ * (a billion guesses gives a ~5% hit rate at 2^64). Longer signatures bloat
22
+ * prerendered HTML for no practical gain.
23
+ */
24
+ import type { H3Event } from 'h3';
25
+ import { PAGE_TOKEN_MAX_AGE, PAGE_TOKEN_PARAM, PAGE_TOKEN_TS_PARAM, SIG_LENGTH, SIG_PARAM } from './sign-constants.js';
26
+ export { PAGE_TOKEN_MAX_AGE, PAGE_TOKEN_PARAM, PAGE_TOKEN_TS_PARAM, SIG_LENGTH, SIG_PARAM };
27
+ /**
28
+ * Canonicalize a query object into a deterministic string suitable for HMAC input.
29
+ *
30
+ * Rules:
31
+ * - The `sig` param is stripped (it can't sign itself).
32
+ * - `undefined` and `null` values are skipped (mirrors `ufo.withQuery`).
33
+ * - Keys are sorted alphabetically so order-independent reconstruction works.
34
+ * - Arrays expand to repeated keys (e.g. `markers=a&markers=b`), matching how
35
+ * `ufo.withQuery` serializes array-valued params.
36
+ * - Objects are JSON-stringified (rare, but consistent with `ufo.withQuery`).
37
+ * - Encoding uses `encodeURIComponent` for both keys and values so the canonical
38
+ * form matches what shows up on the wire.
39
+ *
40
+ * The resulting string is stable across server/client and different JS runtimes
41
+ * because it does not depend on `URLSearchParams` insertion order.
42
+ */
43
+ export declare function canonicalizeQuery(query: Record<string, unknown>): string;
44
+ /**
45
+ * Sign a path + query using HMAC-SHA256 and return the 16-char hex digest.
46
+ *
47
+ * The HMAC input is `${path}?${canonicalQuery}` so that the same query signed
48
+ * against a different endpoint yields a different signature (prevents cross-
49
+ * endpoint signature reuse).
50
+ *
51
+ * `path` should be the URL path without query string (e.g. `/_scripts/proxy/google-static-maps`).
52
+ * Callers should not include origin / host since the signing contract is path-relative.
53
+ */
54
+ export declare function signProxyUrl(path: string, query: Record<string, unknown>, secret: string): string;
55
+ /**
56
+ * Build a fully-formed signed URL (path + query + sig).
57
+ *
58
+ * This is the primary helper for code paths that need to emit a proxy URL
59
+ * (SSR components, server-side URL rewriters like instagram-embed).
60
+ */
61
+ export declare function buildSignedProxyUrl(path: string, query: Record<string, unknown>, secret: string): string;
62
+ /**
63
+ * Generate a page token that authorizes client-side proxy requests.
64
+ *
65
+ * Embedded in the SSR payload so the browser can attach it to reactive proxy
66
+ * URL updates without needing a `/sign` round-trip. The token is scoped to
67
+ * a timestamp and expires after `PAGE_TOKEN_MAX_AGE` seconds.
68
+ *
69
+ * Construction: first 16 hex chars of `HMAC(secret, "proxy-access:<timestamp>")`.
70
+ */
71
+ export declare function generateProxyToken(secret: string, timestamp: number): string;
72
+ /**
73
+ * Verify a page token against the current time.
74
+ *
75
+ * Returns `true` if the token matches the HMAC for the given timestamp AND
76
+ * the timestamp is within `maxAge` seconds of `now`.
77
+ */
78
+ export declare function verifyProxyToken(token: string, timestamp: number, secret: string, maxAge?: number, now?: number): boolean;
79
+ /**
80
+ * Verify a request against either a URL signature or a page token.
81
+ *
82
+ * Two verification modes, checked in order:
83
+ *
84
+ * 1. **URL signature** (`sig` param): the exact URL was signed server-side
85
+ * during SSR/prerender. Locked to the specific path + query params.
86
+ *
87
+ * 2. **Page token** (`_pt` + `_ts` params): the client received a short-lived
88
+ * token during SSR and is making a reactive proxy request with new params.
89
+ * Valid for any params on the target path, but expires after `maxAge`.
90
+ *
91
+ * Returns `false` if neither mode validates.
92
+ */
93
+ export declare function verifyProxyRequest(event: H3Event, secret: string, maxAge?: number): boolean;
94
+ /**
95
+ * Constant-time string comparison.
96
+ *
97
+ * Both inputs are expected to be equal-length hex strings. The loop runs over
98
+ * the longer length so an early-exit on length mismatch doesn't leak the
99
+ * expected length (though both are fixed at `SIG_LENGTH` in practice).
100
+ */
101
+ export declare function constantTimeEqual(a: string, b: string): boolean;
@@ -0,0 +1,91 @@
1
+ import { createHmac } from "node:crypto";
2
+ import { getQuery } from "h3";
3
+ import {
4
+ PAGE_TOKEN_MAX_AGE,
5
+ PAGE_TOKEN_PARAM,
6
+ PAGE_TOKEN_TS_PARAM,
7
+ SIG_LENGTH,
8
+ SIG_PARAM
9
+ } from "./sign-constants.js";
10
+ export { PAGE_TOKEN_MAX_AGE, PAGE_TOKEN_PARAM, PAGE_TOKEN_TS_PARAM, SIG_LENGTH, SIG_PARAM };
11
+ export function canonicalizeQuery(query) {
12
+ const keys = Object.keys(query).filter((k) => k !== SIG_PARAM && query[k] !== void 0 && query[k] !== null).sort();
13
+ const parts = [];
14
+ for (const key of keys) {
15
+ const value = query[key];
16
+ const encodedKey = encodeURIComponent(key);
17
+ if (Array.isArray(value)) {
18
+ for (const item of value) {
19
+ if (item === void 0 || item === null)
20
+ continue;
21
+ parts.push(`${encodedKey}=${encodeURIComponent(serializeValue(item))}`);
22
+ }
23
+ } else {
24
+ parts.push(`${encodedKey}=${encodeURIComponent(serializeValue(value))}`);
25
+ }
26
+ }
27
+ return parts.join("&");
28
+ }
29
+ function serializeValue(value) {
30
+ if (typeof value === "string")
31
+ return value;
32
+ if (typeof value === "object")
33
+ return JSON.stringify(value);
34
+ return String(value);
35
+ }
36
+ export function signProxyUrl(path, query, secret) {
37
+ const canonical = canonicalizeQuery(query);
38
+ const input = canonical ? `${path}?${canonical}` : path;
39
+ return createHmac("sha256", secret).update(input).digest("hex").slice(0, SIG_LENGTH);
40
+ }
41
+ export function buildSignedProxyUrl(path, query, secret) {
42
+ const sig = signProxyUrl(path, query, secret);
43
+ const canonical = canonicalizeQuery(query);
44
+ const queryString = canonical ? `${canonical}&${SIG_PARAM}=${sig}` : `${SIG_PARAM}=${sig}`;
45
+ return `${path}?${queryString}`;
46
+ }
47
+ export function generateProxyToken(secret, timestamp) {
48
+ return createHmac("sha256", secret).update(`proxy-access:${timestamp}`).digest("hex").slice(0, SIG_LENGTH);
49
+ }
50
+ export function verifyProxyToken(token, timestamp, secret, maxAge = PAGE_TOKEN_MAX_AGE, now = Math.floor(Date.now() / 1e3)) {
51
+ if (!token || !secret || typeof timestamp !== "number")
52
+ return false;
53
+ if (token.length !== SIG_LENGTH)
54
+ return false;
55
+ const age = now - timestamp;
56
+ if (age > maxAge || age < -60)
57
+ return false;
58
+ const expected = generateProxyToken(secret, timestamp);
59
+ return constantTimeEqual(expected, token);
60
+ }
61
+ export function verifyProxyRequest(event, secret, maxAge) {
62
+ if (!secret)
63
+ return false;
64
+ const query = getQuery(event);
65
+ const rawSig = query[SIG_PARAM];
66
+ const sig = Array.isArray(rawSig) ? rawSig[0] : rawSig;
67
+ if (typeof sig === "string" && sig.length === SIG_LENGTH) {
68
+ const path = (event.path || "").split("?")[0] || "";
69
+ const expected = signProxyUrl(path, query, secret);
70
+ if (constantTimeEqual(expected, sig))
71
+ return true;
72
+ }
73
+ const rawToken = query[PAGE_TOKEN_PARAM];
74
+ const rawTs = query[PAGE_TOKEN_TS_PARAM];
75
+ const token = Array.isArray(rawToken) ? rawToken[0] : rawToken;
76
+ const ts = Array.isArray(rawTs) ? rawTs[0] : rawTs;
77
+ if (typeof token === "string" && ts !== void 0) {
78
+ const timestamp = Number(ts);
79
+ if (!Number.isNaN(timestamp))
80
+ return verifyProxyToken(token, timestamp, secret, maxAge);
81
+ }
82
+ return false;
83
+ }
84
+ export function constantTimeEqual(a, b) {
85
+ if (a.length !== b.length)
86
+ return false;
87
+ let diff = 0;
88
+ for (let i = 0; i < a.length; i++)
89
+ diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
90
+ return diff === 0;
91
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Middleware wrapper that enforces HMAC signature verification on a proxy handler.
3
+ *
4
+ * Usage:
5
+ * ```ts
6
+ * export default withSigning(defineEventHandler(async (event) => {
7
+ * // ... handler logic
8
+ * }))
9
+ * ```
10
+ *
11
+ * Behavior:
12
+ * - Reads `runtimeConfig.nuxt-scripts.proxySecret` (server-only).
13
+ * - If no secret is configured: passes through (signing not yet enabled).
14
+ * This allows shipping handler wiring before components emit signed URLs.
15
+ * Once `NUXT_SCRIPTS_PROXY_SECRET` is set, verification is enforced.
16
+ * - If a secret IS configured and the request's signature is invalid: 403.
17
+ * - Otherwise, delegates to the wrapped handler.
18
+ *
19
+ * The outer wrapper runs before any handler logic, so unauthorized requests
20
+ * never reach the upstream fetch and cannot consume API quota.
21
+ */
22
+ import type { EventHandler, EventHandlerRequest, EventHandlerResponse } from 'h3';
23
+ export declare function withSigning<Req extends EventHandlerRequest = EventHandlerRequest, Res extends EventHandlerResponse = EventHandlerResponse>(handler: EventHandler<Req, Res>): EventHandler<Req, Res>;