@nuxt/scripts 1.0.0-beta.1 → 1.0.0-beta.13

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 (139) hide show
  1. package/README.md +6 -0
  2. package/dist/client/200.html +1 -1
  3. package/dist/client/404.html +1 -1
  4. package/dist/client/_nuxt/48AF9EJD.js +1 -0
  5. package/dist/client/_nuxt/Bk6ed9rg.js +1 -0
  6. package/dist/client/_nuxt/C4Cj8gBr.js +162 -0
  7. package/dist/client/_nuxt/{DTDyDxvR.js → DP0kj6Xn.js} +1 -1
  8. package/dist/client/_nuxt/builds/latest.json +1 -1
  9. package/dist/client/_nuxt/builds/meta/0e95b1cc-8751-4000-8cb4-a6ef270b636f.json +1 -0
  10. package/dist/client/_nuxt/entry.D45OuV0w.css +1 -0
  11. package/dist/client/_nuxt/error-404.B57D-jUQ.css +1 -0
  12. package/dist/client/_nuxt/error-500.DTHUW7BI.css +1 -0
  13. package/dist/client/index.html +1 -1
  14. package/dist/module.d.mts +87 -2
  15. package/dist/module.d.ts +176 -0
  16. package/dist/module.json +1 -1
  17. package/dist/module.mjs +710 -273
  18. package/dist/registry.d.ts +6 -0
  19. package/dist/registry.mjs +42 -19
  20. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.d.vue.ts +1 -1
  21. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue +6 -6
  22. package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue.d.ts +1 -1
  23. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.vue +6 -6
  24. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsCircle.vue +7 -7
  25. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsHeatmapLayer.vue +6 -6
  26. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.vue +12 -12
  27. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue +6 -6
  28. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.d.vue.ts +1 -1
  29. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue +6 -6
  30. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue.d.ts +1 -1
  31. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.vue +5 -5
  32. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolygon.vue +7 -7
  33. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolyline.vue +7 -7
  34. package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsRectangle.vue +7 -7
  35. package/dist/runtime/components/ScriptCrisp.vue +1 -1
  36. package/dist/runtime/components/ScriptGoogleAdsense.vue +1 -1
  37. package/dist/runtime/components/ScriptInstagramEmbed.d.vue.ts +53 -0
  38. package/dist/runtime/components/ScriptInstagramEmbed.vue +38 -0
  39. package/dist/runtime/components/ScriptInstagramEmbed.vue.d.ts +53 -0
  40. package/dist/runtime/components/ScriptIntercom.vue +4 -3
  41. package/dist/runtime/components/ScriptLoadingIndicator.d.vue.ts +1 -1
  42. package/dist/runtime/components/ScriptLoadingIndicator.vue.d.ts +1 -1
  43. package/dist/runtime/components/ScriptPayPalButtons.d.vue.ts +2 -2
  44. package/dist/runtime/components/ScriptPayPalButtons.vue +13 -11
  45. package/dist/runtime/components/ScriptPayPalButtons.vue.d.ts +2 -2
  46. package/dist/runtime/components/ScriptPayPalMarks.d.vue.ts +2 -2
  47. package/dist/runtime/components/ScriptPayPalMarks.vue +10 -8
  48. package/dist/runtime/components/ScriptPayPalMarks.vue.d.ts +2 -2
  49. package/dist/runtime/components/ScriptPayPalMessages.d.vue.ts +2 -2
  50. package/dist/runtime/components/ScriptPayPalMessages.vue +11 -9
  51. package/dist/runtime/components/ScriptPayPalMessages.vue.d.ts +2 -2
  52. package/dist/runtime/components/ScriptStripePricingTable.vue +2 -2
  53. package/dist/runtime/components/ScriptVimeoPlayer.vue +1 -1
  54. package/dist/runtime/components/ScriptXEmbed.d.vue.ts +82 -0
  55. package/dist/runtime/components/ScriptXEmbed.vue +76 -0
  56. package/dist/runtime/components/ScriptXEmbed.vue.d.ts +82 -0
  57. package/dist/runtime/components/ScriptYouTubePlayer.vue +7 -4
  58. package/dist/runtime/composables/useScript.js +32 -6
  59. package/dist/runtime/composables/useScriptEventPage.js +2 -2
  60. package/dist/runtime/composables/useScriptTriggerConsent.js +1 -1
  61. package/dist/runtime/composables/useScriptTriggerElement.js +1 -1
  62. package/dist/runtime/composables/useScriptTriggerIdleTimeout.js +1 -1
  63. package/dist/runtime/composables/useScriptTriggerServiceWorker.d.ts +7 -0
  64. package/dist/runtime/composables/useScriptTriggerServiceWorker.js +39 -0
  65. package/dist/runtime/registry/clarity.js +21 -25
  66. package/dist/runtime/registry/cloudflare-web-analytics.js +1 -1
  67. package/dist/runtime/registry/crisp.js +1 -1
  68. package/dist/runtime/registry/databuddy-analytics.js +1 -1
  69. package/dist/runtime/registry/fathom-analytics.js +1 -1
  70. package/dist/runtime/registry/google-adsense.js +1 -1
  71. package/dist/runtime/registry/google-analytics.js +2 -2
  72. package/dist/runtime/registry/google-maps.d.ts +1 -1
  73. package/dist/runtime/registry/google-maps.js +1 -1
  74. package/dist/runtime/registry/google-recaptcha.js +2 -2
  75. package/dist/runtime/registry/google-sign-in.js +1 -1
  76. package/dist/runtime/registry/google-tag-manager.d.ts +1 -1
  77. package/dist/runtime/registry/google-tag-manager.js +2 -2
  78. package/dist/runtime/registry/hotjar.js +1 -1
  79. package/dist/runtime/registry/instagram-embed.d.ts +23 -0
  80. package/dist/runtime/registry/instagram-embed.js +22 -0
  81. package/dist/runtime/registry/intercom.js +1 -1
  82. package/dist/runtime/registry/lemon-squeezy.d.ts +0 -1
  83. package/dist/runtime/registry/matomo-analytics.js +2 -2
  84. package/dist/runtime/registry/meta-pixel.js +1 -1
  85. package/dist/runtime/registry/npm.js +1 -1
  86. package/dist/runtime/registry/paypal.d.ts +1 -1
  87. package/dist/runtime/registry/paypal.js +2 -2
  88. package/dist/runtime/registry/plausible-analytics.js +15 -9
  89. package/dist/runtime/registry/posthog.d.ts +3 -2
  90. package/dist/runtime/registry/posthog.js +8 -12
  91. package/dist/runtime/registry/reddit-pixel.js +1 -1
  92. package/dist/runtime/registry/rybbit-analytics.js +5 -3
  93. package/dist/runtime/registry/segment.js +1 -1
  94. package/dist/runtime/registry/snapchat-pixel.js +1 -1
  95. package/dist/runtime/registry/stripe.d.ts +1 -1
  96. package/dist/runtime/registry/stripe.js +1 -1
  97. package/dist/runtime/registry/tiktok-pixel.d.ts +1 -0
  98. package/dist/runtime/registry/tiktok-pixel.js +2 -1
  99. package/dist/runtime/registry/umami-analytics.js +1 -1
  100. package/dist/runtime/registry/vimeo-player.d.ts +2 -2
  101. package/dist/runtime/registry/vimeo-player.js +1 -1
  102. package/dist/runtime/registry/x-embed.d.ts +77 -0
  103. package/dist/runtime/registry/x-embed.js +41 -0
  104. package/dist/runtime/registry/x-pixel.js +1 -1
  105. package/dist/runtime/registry/youtube-player.d.ts +7 -7
  106. package/dist/runtime/registry/youtube-player.js +1 -1
  107. package/dist/runtime/server/google-static-maps-proxy.js +1 -1
  108. package/dist/runtime/server/instagram-embed-asset.d.ts +2 -0
  109. package/dist/runtime/server/instagram-embed-asset.js +42 -0
  110. package/dist/runtime/server/instagram-embed-image.d.ts +2 -0
  111. package/dist/runtime/server/instagram-embed-image.js +54 -0
  112. package/dist/runtime/server/instagram-embed.d.ts +2 -0
  113. package/dist/runtime/server/instagram-embed.js +91 -0
  114. package/dist/runtime/server/proxy-handler.d.ts +6 -0
  115. package/dist/runtime/server/proxy-handler.js +264 -0
  116. package/dist/runtime/server/utils/privacy.d.ts +141 -0
  117. package/dist/runtime/server/utils/privacy.js +324 -0
  118. package/dist/runtime/server/x-embed-image.d.ts +2 -0
  119. package/dist/runtime/server/x-embed-image.js +53 -0
  120. package/dist/runtime/server/x-embed.d.ts +49 -0
  121. package/dist/runtime/server/x-embed.js +31 -0
  122. package/dist/runtime/types.d.ts +51 -22
  123. package/dist/runtime/utils/pure.d.ts +9 -0
  124. package/dist/runtime/utils/pure.js +0 -0
  125. package/dist/runtime/utils.d.ts +3 -3
  126. package/dist/runtime/utils.js +3 -2
  127. package/dist/shared/scripts.DLRgvHQg.mjs +288 -0
  128. package/dist/stats.d.mts +39 -0
  129. package/dist/stats.d.ts +39 -0
  130. package/dist/stats.mjs +711 -0
  131. package/dist/types.d.mts +1 -1
  132. package/package.json +48 -41
  133. package/dist/client/_nuxt/Bdf7Qtwg.js +0 -1
  134. package/dist/client/_nuxt/CoyZWCgl.js +0 -162
  135. package/dist/client/_nuxt/Ds1k3yKJ.js +0 -1
  136. package/dist/client/_nuxt/builds/meta/62574f80-71d4-4f9e-8b96-145c85230d99.json +0 -1
  137. package/dist/client/_nuxt/entry.BjfcJo5q.css +0 -1
  138. package/dist/client/_nuxt/error-404.D45Vtjcx.css +0 -1
  139. package/dist/client/_nuxt/error-500.BOm1rWQf.css +0 -1
@@ -1,6 +1,6 @@
1
- import { useRegistryScript } from "../utils.js";
2
1
  import { any, array, boolean, literal, object, optional, record, string, union } from "#nuxt-scripts-validator";
3
2
  import { logger } from "../logger.js";
3
+ import { useRegistryScript } from "../utils.js";
4
4
  const extensions = [
5
5
  literal("hash"),
6
6
  literal("outbound-links"),
@@ -55,12 +55,18 @@ export function useScriptPlausibleAnalytics(_options) {
55
55
  scriptSrc = "https://plausible.io/js/script.js";
56
56
  }
57
57
  const initOptions = {};
58
- if (options?.customProperties) initOptions.customProperties = options.customProperties;
59
- if (options?.endpoint) initOptions.endpoint = options.endpoint;
60
- if (options?.fileDownloads) initOptions.fileDownloads = options.fileDownloads;
61
- if (options?.hashBasedRouting !== void 0) initOptions.hashBasedRouting = options.hashBasedRouting;
62
- if (options?.autoCapturePageviews !== void 0) initOptions.autoCapturePageviews = options.autoCapturePageviews;
63
- if (options?.captureOnLocalhost !== void 0) initOptions.captureOnLocalhost = options.captureOnLocalhost;
58
+ if (options?.customProperties)
59
+ initOptions.customProperties = options.customProperties;
60
+ if (options?.endpoint)
61
+ initOptions.endpoint = options.endpoint;
62
+ if (options?.fileDownloads)
63
+ initOptions.fileDownloads = options.fileDownloads;
64
+ if (options?.hashBasedRouting !== void 0)
65
+ initOptions.hashBasedRouting = options.hashBasedRouting;
66
+ if (options?.autoCapturePageviews !== void 0)
67
+ initOptions.autoCapturePageviews = options.autoCapturePageviews;
68
+ if (options?.captureOnLocalhost !== void 0)
69
+ initOptions.captureOnLocalhost = options.captureOnLocalhost;
64
70
  const scriptInput = !useNewScript && options?.domain ? {
65
71
  "src": scriptSrc,
66
72
  "data-domain": options.domain
@@ -76,8 +82,8 @@ export function useScriptPlausibleAnalytics(_options) {
76
82
  },
77
83
  clientInit: import.meta.server ? void 0 : () => {
78
84
  const w = window;
79
- w.plausible = w.plausible || function() {
80
- (w.plausible.q = w.plausible.q || []).push(arguments);
85
+ w.plausible = w.plausible || function(...args) {
86
+ (w.plausible.q = w.plausible.q || []).push(args);
81
87
  };
82
88
  w.plausible.init = w.plausible.init || function(i) {
83
89
  w.plausible.o = i || {};
@@ -1,10 +1,11 @@
1
- import type { PostHog } from 'posthog-js';
2
1
  import type { RegistryScriptInput } from '#nuxt-scripts/types';
2
+ import type { PostHog } from 'posthog-js';
3
3
  export declare const PostHogOptions: import("valibot").ObjectSchema<{
4
4
  readonly apiKey: import("valibot").StringSchema<undefined>;
5
5
  readonly region: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"us", undefined>, import("valibot").LiteralSchema<"eu", undefined>], undefined>, undefined>;
6
+ readonly apiHost: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
6
7
  readonly autocapture: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
7
- readonly capturePageview: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
8
+ readonly capturePageview: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").BooleanSchema<undefined>, import("valibot").LiteralSchema<"history_change", undefined>], undefined>, undefined>;
8
9
  readonly capturePageleave: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
9
10
  readonly disableSessionRecording: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
10
11
  readonly config: import("valibot").OptionalSchema<import("valibot").RecordSchema<import("valibot").StringSchema<undefined>, import("valibot").AnySchema, undefined>, undefined>;
@@ -1,11 +1,12 @@
1
- import { any, record, string, object, optional, boolean, union, literal } from "#nuxt-scripts-validator";
2
- import { useRegistryScript } from "../utils.js";
1
+ import { any, boolean, literal, object, optional, record, string, union } from "#nuxt-scripts-validator";
3
2
  import { logger } from "../logger.js";
3
+ import { useRegistryScript } from "../utils.js";
4
4
  export const PostHogOptions = object({
5
5
  apiKey: string(),
6
6
  region: optional(union([literal("us"), literal("eu")])),
7
+ apiHost: optional(string()),
7
8
  autocapture: optional(boolean()),
8
- capturePageview: optional(boolean()),
9
+ capturePageview: optional(union([boolean(), literal("history_change")])),
9
10
  capturePageleave: optional(boolean()),
10
11
  disableSessionRecording: optional(boolean()),
11
12
  config: optional(record(string(), any()))
@@ -47,41 +48,36 @@ export function useScriptPostHog(_options) {
47
48
  return;
48
49
  }
49
50
  const region = options?.region || "us";
50
- const apiHost = region === "eu" ? "https://eu.i.posthog.com" : "https://us.i.posthog.com";
51
- console.log("[PostHog] Starting dynamic import of posthog-js...");
51
+ let apiHost = options?.apiHost || (region === "eu" ? "https://eu.i.posthog.com" : "https://us.i.posthog.com");
52
+ if (apiHost.startsWith("/"))
53
+ apiHost = window.location.origin + apiHost;
52
54
  window.__posthogInitPromise = import("posthog-js").then(({ default: posthog }) => {
53
- console.log("[PostHog] posthog-js imported successfully");
54
55
  const config = {
55
56
  api_host: apiHost,
56
57
  ...options?.config
57
58
  };
58
59
  if (typeof options?.autocapture === "boolean")
59
60
  config.autocapture = options.autocapture;
60
- if (typeof options?.capturePageview === "boolean")
61
+ if (typeof options?.capturePageview === "boolean" || options?.capturePageview === "history_change")
61
62
  config.capture_pageview = options.capturePageview;
62
63
  if (typeof options?.capturePageleave === "boolean")
63
64
  config.capture_pageleave = options.capturePageleave;
64
65
  if (typeof options?.disableSessionRecording === "boolean")
65
66
  config.disable_session_recording = options.disableSessionRecording;
66
- console.log("[PostHog] Calling posthog.init with apiKey:", options.apiKey, "config:", config);
67
67
  const instance = posthog.init(options.apiKey, config);
68
68
  if (!instance) {
69
69
  logger.error("PostHog init returned undefined - initialization failed");
70
70
  delete window._posthogQueue;
71
71
  return void 0;
72
72
  }
73
- console.log("[PostHog] posthog.init succeeded, instance:", instance);
74
73
  window.posthog = instance;
75
74
  if (window._posthogQueue && window._posthogQueue.length > 0) {
76
- console.log("[PostHog] Flushing", window._posthogQueue.length, "queued calls");
77
75
  window._posthogQueue.forEach((q) => window.posthog[q.prop]?.(...q.args));
78
76
  delete window._posthogQueue;
79
77
  }
80
- console.log("[PostHog] Initialization complete!");
81
78
  return window.posthog;
82
79
  }).catch((e) => {
83
80
  logger.error("Failed to load posthog-js:", e);
84
- console.error("[PostHog] Import/init error:", e);
85
81
  delete window._posthogQueue;
86
82
  return void 0;
87
83
  });
@@ -1,5 +1,5 @@
1
- import { useRegistryScript } from "../utils.js";
2
1
  import { object, string } from "#nuxt-scripts-validator";
2
+ import { useRegistryScript } from "../utils.js";
3
3
  export const RedditPixelOptions = object({
4
4
  id: string()
5
5
  });
@@ -1,5 +1,5 @@
1
- import { useRegistryScript } from "../utils.js";
2
1
  import { array, boolean, number, object, optional, string, union } from "#nuxt-scripts-validator";
2
+ import { useRegistryScript } from "../utils.js";
3
3
  export const RybbitAnalyticsOptions = object({
4
4
  siteId: union([string(), number()]),
5
5
  // required
@@ -17,7 +17,8 @@ export const RybbitAnalyticsOptions = object({
17
17
  });
18
18
  const RYBBIT_QUEUE_KEY = Symbol.for("nuxt-scripts.rybbit-queue");
19
19
  function getRybbitState() {
20
- if (!import.meta.client) return;
20
+ if (!import.meta.client)
21
+ return;
21
22
  const g = globalThis;
22
23
  if (!g[RYBBIT_QUEUE_KEY]) {
23
24
  g[RYBBIT_QUEUE_KEY] = { queue: [], flushed: false };
@@ -28,7 +29,8 @@ export function useScriptRybbitAnalytics(_options) {
28
29
  const isRybbitReady = () => import.meta.client && typeof window !== "undefined" && window.rybbit && typeof window.rybbit.event === "function";
29
30
  const flushQueue = () => {
30
31
  const state = getRybbitState();
31
- if (!state || state.flushed || !isRybbitReady()) return;
32
+ if (!state || state.flushed || !isRybbitReady())
33
+ return;
32
34
  state.flushed = true;
33
35
  while (state.queue.length > 0) {
34
36
  const [method, ...args] = state.queue.shift();
@@ -1,6 +1,6 @@
1
+ import { object, optional, string } from "#nuxt-scripts-validator";
1
2
  import { joinURL } from "ufo";
2
3
  import { useRegistryScript } from "../utils.js";
3
- import { object, optional, string } from "#nuxt-scripts-validator";
4
4
  export const SegmentOptions = object({
5
5
  writeKey: string(),
6
6
  analyticsKey: optional(string())
@@ -1,5 +1,5 @@
1
- import { useRegistryScript } from "../utils.js";
2
1
  import { boolean, object, optional, string } from "#nuxt-scripts-validator";
2
+ import { useRegistryScript } from "../utils.js";
3
3
  export const InitObjectPropertiesSchema = object({
4
4
  user_email: optional(string()),
5
5
  ip_address: optional(string()),
@@ -1,5 +1,5 @@
1
- import type { StripeConstructor } from '@stripe/stripe-js';
2
1
  import type { RegistryScriptInput } from '#nuxt-scripts/types';
2
+ import type { StripeConstructor } from '@stripe/stripe-js';
3
3
  export declare const StripeOptions: import("valibot").ObjectSchema<{
4
4
  readonly advancedFraudSignals: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
5
5
  }, undefined>;
@@ -1,6 +1,6 @@
1
+ import { boolean, object, optional } from "#nuxt-scripts-validator";
1
2
  import { withQuery } from "ufo";
2
3
  import { useRegistryScript } from "../utils.js";
3
- import { boolean, object, optional } from "#nuxt-scripts-validator";
4
4
  export const StripeOptions = object({
5
5
  advancedFraudSignals: optional(boolean())
6
6
  });
@@ -32,6 +32,7 @@ export interface TikTokPixelApi {
32
32
  }
33
33
  declare global {
34
34
  interface Window extends TikTokPixelApi {
35
+ TiktokAnalyticsObject: string;
35
36
  }
36
37
  }
37
38
  export declare const TikTokPixelOptions: import("valibot").ObjectSchema<{
@@ -1,6 +1,6 @@
1
+ import { boolean, object, optional, string } from "#nuxt-scripts-validator";
1
2
  import { withQuery } from "ufo";
2
3
  import { useRegistryScript } from "../utils.js";
3
- import { object, string, optional, boolean } from "#nuxt-scripts-validator";
4
4
  export const TikTokPixelOptions = object({
5
5
  id: string(),
6
6
  trackPageView: optional(boolean())
@@ -22,6 +22,7 @@ export function useScriptTikTokPixel(_options) {
22
22
  }
23
23
  },
24
24
  clientInit: import.meta.server ? void 0 : () => {
25
+ window.TiktokAnalyticsObject = "ttq";
25
26
  const ttq = window.ttq = function(...params) {
26
27
  if (ttq.callMethod) {
27
28
  ttq.callMethod(...params);
@@ -1,5 +1,5 @@
1
+ import { array, boolean, custom, object, optional, string, union } from "#nuxt-scripts-validator";
1
2
  import { useRegistryScript } from "../utils.js";
2
- import { object, optional, string, boolean, array, union, custom } from "#nuxt-scripts-validator";
3
3
  export const UmamiAnalyticsOptions = object({
4
4
  websiteId: string(),
5
5
  // required
@@ -1,6 +1,6 @@
1
- import type Vimeo from '@vimeo/player';
2
- import type { UseScriptContext } from '@unhead/vue';
3
1
  import type { RegistryScriptInput } from '#nuxt-scripts/types';
2
+ import type { UseScriptContext } from '@unhead/vue';
3
+ import type Vimeo from '@vimeo/player';
4
4
  type Constructor<T extends new (...args: any) => any> = T extends new (...args: infer A) => infer R ? new (...args: A) => R : never;
5
5
  export interface VimeoPlayerApi {
6
6
  Vimeo: {
@@ -1,5 +1,5 @@
1
- import { watch } from "vue";
2
1
  import { useHead } from "@unhead/vue";
2
+ import { watch } from "vue";
3
3
  import { useRegistryScript } from "../utils.js";
4
4
  export function useScriptVimeoPlayer(_options) {
5
5
  const instance = useRegistryScript("vimeoPlayer", () => ({
@@ -0,0 +1,77 @@
1
+ import type { RegistryScriptInput } from '#nuxt-scripts/types';
2
+ export interface XEmbedTweetData {
3
+ id_str: string;
4
+ text: string;
5
+ created_at: string;
6
+ favorite_count: number;
7
+ conversation_count: number;
8
+ user: {
9
+ name: string;
10
+ screen_name: string;
11
+ profile_image_url_https: string;
12
+ verified?: boolean;
13
+ is_blue_verified?: boolean;
14
+ };
15
+ entities?: {
16
+ media?: Array<{
17
+ media_url_https: string;
18
+ type: string;
19
+ sizes: Record<string, {
20
+ w: number;
21
+ h: number;
22
+ }>;
23
+ }>;
24
+ urls?: Array<{
25
+ url: string;
26
+ expanded_url: string;
27
+ display_url: string;
28
+ }>;
29
+ };
30
+ photos?: Array<{
31
+ url: string;
32
+ width: number;
33
+ height: number;
34
+ }>;
35
+ video?: {
36
+ poster: string;
37
+ variants: Array<{
38
+ type: string;
39
+ src: string;
40
+ }>;
41
+ };
42
+ quoted_tweet?: XEmbedTweetData;
43
+ parent?: {
44
+ user: {
45
+ screen_name: string;
46
+ };
47
+ };
48
+ }
49
+ export declare const XEmbedOptions: import("valibot").ObjectSchema<{
50
+ /**
51
+ * The tweet ID to embed
52
+ */
53
+ readonly tweetId: import("valibot").StringSchema<undefined>;
54
+ /**
55
+ * Optional: Custom API endpoint for fetching tweet data
56
+ * @default '/api/_scripts/x-embed'
57
+ */
58
+ readonly apiEndpoint: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
59
+ /**
60
+ * Optional: Custom image proxy endpoint
61
+ * @default '/api/_scripts/x-embed-image'
62
+ */
63
+ readonly imageProxyEndpoint: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
64
+ }, undefined>;
65
+ export type XEmbedInput = RegistryScriptInput<typeof XEmbedOptions, false, false, false>;
66
+ /**
67
+ * Proxy an X/Twitter image URL through the server
68
+ */
69
+ export declare function proxyXImageUrl(url: string, proxyEndpoint?: string): string;
70
+ /**
71
+ * Format a tweet date for display
72
+ */
73
+ export declare function formatTweetDate(dateString: string): string;
74
+ /**
75
+ * Format a number for display (e.g., 1234 -> 1.2K)
76
+ */
77
+ export declare function formatCount(count: number): string;
@@ -0,0 +1,41 @@
1
+ import { object, optional, string } from "#nuxt-scripts-validator";
2
+ export const XEmbedOptions = object({
3
+ /**
4
+ * The tweet ID to embed
5
+ */
6
+ tweetId: string(),
7
+ /**
8
+ * Optional: Custom API endpoint for fetching tweet data
9
+ * @default '/api/_scripts/x-embed'
10
+ */
11
+ apiEndpoint: optional(string()),
12
+ /**
13
+ * Optional: Custom image proxy endpoint
14
+ * @default '/api/_scripts/x-embed-image'
15
+ */
16
+ imageProxyEndpoint: optional(string())
17
+ });
18
+ export function proxyXImageUrl(url, proxyEndpoint = "/api/_scripts/x-embed-image") {
19
+ const separator = proxyEndpoint.includes("?") ? "&" : "?";
20
+ return `${proxyEndpoint}${separator}url=${encodeURIComponent(url)}`;
21
+ }
22
+ export function formatTweetDate(dateString) {
23
+ const date = new Date(dateString);
24
+ const time = date.toLocaleString("en-US", {
25
+ hour: "numeric",
26
+ minute: "numeric",
27
+ hour12: true,
28
+ timeZone: "UTC"
29
+ });
30
+ const day = date.toLocaleString("en-US", { month: "short", timeZone: "UTC" });
31
+ return `${time} \xB7 ${day} ${date.getUTCDate()}, ${date.getUTCFullYear()}`;
32
+ }
33
+ export function formatCount(count) {
34
+ if (count >= 1e6) {
35
+ return `${(count / 1e6).toFixed(1)}M`;
36
+ }
37
+ if (count >= 1e3) {
38
+ return `${(count / 1e3).toFixed(1)}K`;
39
+ }
40
+ return count.toString();
41
+ }
@@ -1,5 +1,5 @@
1
- import { useRegistryScript } from "../utils.js";
2
1
  import { object, optional, string } from "#nuxt-scripts-validator";
2
+ import { useRegistryScript } from "../utils.js";
3
3
  export const XPixelOptions = object({
4
4
  id: string(),
5
5
  version: optional(string())
@@ -1,18 +1,18 @@
1
+ import type { RegistryScriptInput } from '#nuxt-scripts/types';
1
2
  import type { UseScriptContext } from '@unhead/vue';
2
3
  import type { MaybePromise } from '../utils.js';
3
- import type { RegistryScriptInput } from '#nuxt-scripts/types';
4
4
  export interface YouTubePlayerApi {
5
5
  YT: MaybePromise<{
6
6
  Player: YT.Player;
7
7
  PlayerState: YT.PlayerState;
8
- get(k: string): any;
8
+ get: (k: string) => any;
9
9
  loaded: 0 | 1;
10
10
  loading: 0 | 1;
11
- ready(f: () => void): void;
12
- scan(): void;
13
- setConfig(config: YT.PlayerOptions): void;
14
- subscribe<EventName extends keyof YT.Events>(event: EventName, listener: YT.Events[EventName], context?: any): void;
15
- unsubscribe<EventName extends keyof YT.Events>(event: EventName, listener: YT.Events[EventName], context?: any): void;
11
+ ready: (f: () => void) => void;
12
+ scan: () => void;
13
+ setConfig: (config: YT.PlayerOptions) => void;
14
+ subscribe: <EventName extends keyof YT.Events>(event: EventName, listener: YT.Events[EventName], context?: any) => void;
15
+ unsubscribe: <EventName extends keyof YT.Events>(event: EventName, listener: YT.Events[EventName], context?: any) => void;
16
16
  }>;
17
17
  }
18
18
  declare global {
@@ -1,5 +1,5 @@
1
- import { watch } from "vue";
2
1
  import { useHead } from "@unhead/vue";
2
+ import { watch } from "vue";
3
3
  import { useRegistryScript } from "../utils.js";
4
4
  export function useScriptYouTubePlayer(_options) {
5
5
  let readyPromise = Promise.resolve();
@@ -1,7 +1,7 @@
1
+ import { useRuntimeConfig } from "#imports";
1
2
  import { createError, defineEventHandler, getHeader, getQuery, setHeader } from "h3";
2
3
  import { $fetch } from "ofetch";
3
4
  import { withQuery } from "ufo";
4
- import { useRuntimeConfig } from "#imports";
5
5
  export default defineEventHandler(async (event) => {
6
6
  const runtimeConfig = useRuntimeConfig();
7
7
  const publicConfig = runtimeConfig.public["nuxt-scripts"]?.googleStaticMapsProxy;
@@ -0,0 +1,2 @@
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
2
+ export default _default;
@@ -0,0 +1,42 @@
1
+ import { createError, defineEventHandler, getQuery, setHeader } from "h3";
2
+ import { $fetch } from "ofetch";
3
+ export default defineEventHandler(async (event) => {
4
+ const query = getQuery(event);
5
+ const url = query.url?.replace(/&amp;/g, "&");
6
+ if (!url) {
7
+ throw createError({
8
+ statusCode: 400,
9
+ statusMessage: "Asset URL is required"
10
+ });
11
+ }
12
+ let parsedUrl;
13
+ try {
14
+ parsedUrl = new URL(url);
15
+ } catch {
16
+ throw createError({
17
+ statusCode: 400,
18
+ statusMessage: "Invalid asset URL"
19
+ });
20
+ }
21
+ if (parsedUrl.hostname !== "static.cdninstagram.com") {
22
+ throw createError({
23
+ statusCode: 403,
24
+ statusMessage: "Domain not allowed"
25
+ });
26
+ }
27
+ const response = await $fetch.raw(url, {
28
+ headers: {
29
+ "Accept": "*/*",
30
+ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
31
+ }
32
+ }).catch((error) => {
33
+ throw createError({
34
+ statusCode: error.statusCode || 500,
35
+ statusMessage: error.statusMessage || "Failed to fetch asset"
36
+ });
37
+ });
38
+ const contentType = response.headers.get("content-type") || "application/octet-stream";
39
+ setHeader(event, "Content-Type", contentType);
40
+ setHeader(event, "Cache-Control", "public, max-age=86400, s-maxage=86400");
41
+ return response._data;
42
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
2
+ export default _default;
@@ -0,0 +1,54 @@
1
+ import { createError, defineEventHandler, getQuery, setHeader } from "h3";
2
+ import { $fetch } from "ofetch";
3
+ export default defineEventHandler(async (event) => {
4
+ const query = getQuery(event);
5
+ const url = query.url?.replace(/&amp;/g, "&");
6
+ if (!url) {
7
+ throw createError({
8
+ statusCode: 400,
9
+ statusMessage: "Image URL is required"
10
+ });
11
+ }
12
+ let parsedUrl;
13
+ try {
14
+ parsedUrl = new URL(url);
15
+ } catch {
16
+ throw createError({
17
+ statusCode: 400,
18
+ statusMessage: "Invalid image URL"
19
+ });
20
+ }
21
+ if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") {
22
+ throw createError({
23
+ statusCode: 400,
24
+ statusMessage: "Invalid URL scheme"
25
+ });
26
+ }
27
+ if (!parsedUrl.hostname.endsWith(".cdninstagram.com") && parsedUrl.hostname !== "scontent.cdninstagram.com") {
28
+ throw createError({
29
+ statusCode: 403,
30
+ statusMessage: "Domain not allowed"
31
+ });
32
+ }
33
+ const response = await $fetch.raw(url, {
34
+ redirect: "manual",
35
+ headers: {
36
+ "Accept": "image/webp,image/jpeg,image/png,image/*,*/*;q=0.8",
37
+ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
38
+ }
39
+ }).catch((error) => {
40
+ throw createError({
41
+ statusCode: error.statusCode || 500,
42
+ statusMessage: error.statusMessage || "Failed to fetch image"
43
+ });
44
+ });
45
+ if (response.status >= 300 && response.status < 400) {
46
+ throw createError({
47
+ statusCode: 403,
48
+ statusMessage: "Redirects not allowed"
49
+ });
50
+ }
51
+ setHeader(event, "Content-Type", response.headers.get("content-type") || "image/jpeg");
52
+ setHeader(event, "Cache-Control", "public, max-age=3600, s-maxage=3600");
53
+ return response._data;
54
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<string>>;
2
+ export default _default;
@@ -0,0 +1,91 @@
1
+ import { createError, defineEventHandler, getQuery, setHeader } from "h3";
2
+ import { $fetch } from "ofetch";
3
+ export default defineEventHandler(async (event) => {
4
+ const query = getQuery(event);
5
+ const postUrl = query.url;
6
+ const captions = query.captions === "true";
7
+ if (!postUrl) {
8
+ throw createError({
9
+ statusCode: 400,
10
+ statusMessage: "Post URL is required"
11
+ });
12
+ }
13
+ let parsedUrl;
14
+ try {
15
+ parsedUrl = new URL(postUrl);
16
+ } catch {
17
+ throw createError({
18
+ statusCode: 400,
19
+ statusMessage: "Invalid postUrl"
20
+ });
21
+ }
22
+ if (!["instagram.com", "www.instagram.com"].includes(parsedUrl.hostname)) {
23
+ throw createError({
24
+ statusCode: 400,
25
+ statusMessage: "Invalid Instagram URL"
26
+ });
27
+ }
28
+ const pathname = parsedUrl.pathname.endsWith("/") ? parsedUrl.pathname : `${parsedUrl.pathname}/`;
29
+ const cleanUrl = parsedUrl.origin + pathname;
30
+ const embedUrl = `${cleanUrl}embed/${captions ? "captioned/" : ""}`;
31
+ const html = await $fetch(embedUrl, {
32
+ headers: {
33
+ "Accept": "text/html",
34
+ // Use simple UA - full Chrome UA triggers JS-heavy version without static content
35
+ "User-Agent": "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
36
+ }
37
+ }).catch((error) => {
38
+ throw createError({
39
+ statusCode: error.statusCode || 500,
40
+ statusMessage: error.statusMessage || "Failed to fetch Instagram embed"
41
+ });
42
+ });
43
+ const cssUrls = [];
44
+ const linkRegex = /<link[^>]+rel=["']stylesheet["'][^>]+href=["']([^"']+)["'][^>]*>/gi;
45
+ let match;
46
+ while ((match = linkRegex.exec(html)) !== null) {
47
+ if (match[1])
48
+ cssUrls.push(match[1]);
49
+ }
50
+ const linkRegex2 = /<link[^>]+href=["']([^"']+)["'][^>]+rel=["']stylesheet["'][^>]*>/gi;
51
+ while ((match = linkRegex2.exec(html)) !== null) {
52
+ if (match[1])
53
+ cssUrls.push(match[1]);
54
+ }
55
+ const cssContents = await Promise.all(
56
+ cssUrls.map(
57
+ (url) => $fetch(url, {
58
+ headers: { Accept: "text/css" }
59
+ }).catch(() => "")
60
+ )
61
+ );
62
+ let combinedCss = cssContents.join("\n");
63
+ combinedCss = combinedCss.replace(
64
+ /url\(\/rsrc\.php([^)]+)\)/g,
65
+ (_m, path) => `url(/api/_scripts/instagram-embed-asset?url=${encodeURIComponent(`https://static.cdninstagram.com/rsrc.php${path}`)})`
66
+ );
67
+ const baseStyles = `
68
+ html { background: white; max-width: 540px; width: calc(100% - 2px); border-radius: 3px; border: 1px solid rgb(219, 219, 219); display: block; margin: 0px 0px 12px; min-width: 326px; padding: 0px; }
69
+ #splash-screen { display: none !important; }
70
+ .Embed { opacity: 1 !important; visibility: visible !important; }
71
+ .EmbeddedMedia, .EmbeddedMediaImage { display: block !important; visibility: visible !important; }
72
+ `;
73
+ let rewrittenHtml = html.replace(/<script[\s\S]*?<\/script>/gi, "").replace(/<link[^>]+rel=["']stylesheet["'][^>]*>/gi, "").replace(/<link[^>]+href=["'][^"']+\.css[^"']*["'][^>]*>/gi, "").replace(/<noscript>[\s\S]*?<\/noscript>/gi, "").replace(
74
+ /https:\/\/scontent[^"'\s),]+\.cdninstagram\.com[^"'\s),]+/g,
75
+ (m) => `/api/_scripts/instagram-embed-image?url=${encodeURIComponent(m.replace(/&amp;/g, "&"))}`
76
+ ).replace(
77
+ /https:\/\/static\.cdninstagram\.com[^"'\s),]+/g,
78
+ (m) => `/api/_scripts/instagram-embed-asset?url=${encodeURIComponent(m.replace(/&amp;/g, "&"))}`
79
+ ).replace(
80
+ /https:\/\/lookaside\.instagram\.com[^"'\s),]+/g,
81
+ (m) => `/api/_scripts/instagram-embed-image?url=${encodeURIComponent(m.replace(/&amp;/g, "&"))}`
82
+ );
83
+ rewrittenHtml = rewrittenHtml.replace(
84
+ "</head>",
85
+ `<style>${baseStyles}
86
+ ${combinedCss}</style></head>`
87
+ );
88
+ setHeader(event, "Content-Type", "text/html");
89
+ setHeader(event, "Cache-Control", "public, max-age=600, s-maxage=600");
90
+ return rewrittenHtml;
91
+ });
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Privacy-aware proxy handler for first-party script collection endpoints.
3
+ * Routes requests to third-party analytics while protecting user privacy.
4
+ */
5
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<string | Buffer<ArrayBuffer>>>;
6
+ export default _default;