@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.
- package/README.md +6 -0
- package/dist/client/200.html +1 -1
- package/dist/client/404.html +1 -1
- package/dist/client/_nuxt/48AF9EJD.js +1 -0
- package/dist/client/_nuxt/Bk6ed9rg.js +1 -0
- package/dist/client/_nuxt/C4Cj8gBr.js +162 -0
- package/dist/client/_nuxt/{DTDyDxvR.js → DP0kj6Xn.js} +1 -1
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/0e95b1cc-8751-4000-8cb4-a6ef270b636f.json +1 -0
- package/dist/client/_nuxt/entry.D45OuV0w.css +1 -0
- package/dist/client/_nuxt/error-404.B57D-jUQ.css +1 -0
- package/dist/client/_nuxt/error-500.DTHUW7BI.css +1 -0
- package/dist/client/index.html +1 -1
- package/dist/module.d.mts +87 -2
- package/dist/module.d.ts +176 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +710 -273
- package/dist/registry.d.ts +6 -0
- package/dist/registry.mjs +42 -19
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.d.vue.ts +1 -1
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue +6 -6
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue.d.ts +1 -1
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.vue +6 -6
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsCircle.vue +7 -7
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsHeatmapLayer.vue +6 -6
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.vue +12 -12
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue +6 -6
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.d.vue.ts +1 -1
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue +6 -6
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue.d.ts +1 -1
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.vue +5 -5
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolygon.vue +7 -7
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolyline.vue +7 -7
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsRectangle.vue +7 -7
- package/dist/runtime/components/ScriptCrisp.vue +1 -1
- package/dist/runtime/components/ScriptGoogleAdsense.vue +1 -1
- package/dist/runtime/components/ScriptInstagramEmbed.d.vue.ts +53 -0
- package/dist/runtime/components/ScriptInstagramEmbed.vue +38 -0
- package/dist/runtime/components/ScriptInstagramEmbed.vue.d.ts +53 -0
- package/dist/runtime/components/ScriptIntercom.vue +4 -3
- package/dist/runtime/components/ScriptLoadingIndicator.d.vue.ts +1 -1
- package/dist/runtime/components/ScriptLoadingIndicator.vue.d.ts +1 -1
- package/dist/runtime/components/ScriptPayPalButtons.d.vue.ts +2 -2
- package/dist/runtime/components/ScriptPayPalButtons.vue +13 -11
- package/dist/runtime/components/ScriptPayPalButtons.vue.d.ts +2 -2
- package/dist/runtime/components/ScriptPayPalMarks.d.vue.ts +2 -2
- package/dist/runtime/components/ScriptPayPalMarks.vue +10 -8
- package/dist/runtime/components/ScriptPayPalMarks.vue.d.ts +2 -2
- package/dist/runtime/components/ScriptPayPalMessages.d.vue.ts +2 -2
- package/dist/runtime/components/ScriptPayPalMessages.vue +11 -9
- package/dist/runtime/components/ScriptPayPalMessages.vue.d.ts +2 -2
- package/dist/runtime/components/ScriptStripePricingTable.vue +2 -2
- package/dist/runtime/components/ScriptVimeoPlayer.vue +1 -1
- package/dist/runtime/components/ScriptXEmbed.d.vue.ts +82 -0
- package/dist/runtime/components/ScriptXEmbed.vue +76 -0
- package/dist/runtime/components/ScriptXEmbed.vue.d.ts +82 -0
- package/dist/runtime/components/ScriptYouTubePlayer.vue +7 -4
- package/dist/runtime/composables/useScript.js +32 -6
- package/dist/runtime/composables/useScriptEventPage.js +2 -2
- package/dist/runtime/composables/useScriptTriggerConsent.js +1 -1
- package/dist/runtime/composables/useScriptTriggerElement.js +1 -1
- package/dist/runtime/composables/useScriptTriggerIdleTimeout.js +1 -1
- package/dist/runtime/composables/useScriptTriggerServiceWorker.d.ts +7 -0
- package/dist/runtime/composables/useScriptTriggerServiceWorker.js +39 -0
- package/dist/runtime/registry/clarity.js +21 -25
- package/dist/runtime/registry/cloudflare-web-analytics.js +1 -1
- package/dist/runtime/registry/crisp.js +1 -1
- package/dist/runtime/registry/databuddy-analytics.js +1 -1
- package/dist/runtime/registry/fathom-analytics.js +1 -1
- package/dist/runtime/registry/google-adsense.js +1 -1
- package/dist/runtime/registry/google-analytics.js +2 -2
- package/dist/runtime/registry/google-maps.d.ts +1 -1
- package/dist/runtime/registry/google-maps.js +1 -1
- package/dist/runtime/registry/google-recaptcha.js +2 -2
- package/dist/runtime/registry/google-sign-in.js +1 -1
- package/dist/runtime/registry/google-tag-manager.d.ts +1 -1
- package/dist/runtime/registry/google-tag-manager.js +2 -2
- package/dist/runtime/registry/hotjar.js +1 -1
- package/dist/runtime/registry/instagram-embed.d.ts +23 -0
- package/dist/runtime/registry/instagram-embed.js +22 -0
- package/dist/runtime/registry/intercom.js +1 -1
- package/dist/runtime/registry/lemon-squeezy.d.ts +0 -1
- package/dist/runtime/registry/matomo-analytics.js +2 -2
- package/dist/runtime/registry/meta-pixel.js +1 -1
- package/dist/runtime/registry/npm.js +1 -1
- package/dist/runtime/registry/paypal.d.ts +1 -1
- package/dist/runtime/registry/paypal.js +2 -2
- package/dist/runtime/registry/plausible-analytics.js +15 -9
- package/dist/runtime/registry/posthog.d.ts +3 -2
- package/dist/runtime/registry/posthog.js +8 -12
- package/dist/runtime/registry/reddit-pixel.js +1 -1
- package/dist/runtime/registry/rybbit-analytics.js +5 -3
- package/dist/runtime/registry/segment.js +1 -1
- package/dist/runtime/registry/snapchat-pixel.js +1 -1
- package/dist/runtime/registry/stripe.d.ts +1 -1
- package/dist/runtime/registry/stripe.js +1 -1
- package/dist/runtime/registry/tiktok-pixel.d.ts +1 -0
- package/dist/runtime/registry/tiktok-pixel.js +2 -1
- package/dist/runtime/registry/umami-analytics.js +1 -1
- 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 +77 -0
- package/dist/runtime/registry/x-embed.js +41 -0
- package/dist/runtime/registry/x-pixel.js +1 -1
- package/dist/runtime/registry/youtube-player.d.ts +7 -7
- package/dist/runtime/registry/youtube-player.js +1 -1
- package/dist/runtime/server/google-static-maps-proxy.js +1 -1
- package/dist/runtime/server/instagram-embed-asset.d.ts +2 -0
- package/dist/runtime/server/instagram-embed-asset.js +42 -0
- package/dist/runtime/server/instagram-embed-image.d.ts +2 -0
- package/dist/runtime/server/instagram-embed-image.js +54 -0
- package/dist/runtime/server/instagram-embed.d.ts +2 -0
- package/dist/runtime/server/instagram-embed.js +91 -0
- package/dist/runtime/server/proxy-handler.d.ts +6 -0
- package/dist/runtime/server/proxy-handler.js +264 -0
- package/dist/runtime/server/utils/privacy.d.ts +141 -0
- package/dist/runtime/server/utils/privacy.js +324 -0
- package/dist/runtime/server/x-embed-image.d.ts +2 -0
- package/dist/runtime/server/x-embed-image.js +53 -0
- package/dist/runtime/server/x-embed.d.ts +49 -0
- package/dist/runtime/server/x-embed.js +31 -0
- package/dist/runtime/types.d.ts +51 -22
- package/dist/runtime/utils/pure.d.ts +9 -0
- package/dist/runtime/utils/pure.js +0 -0
- package/dist/runtime/utils.d.ts +3 -3
- package/dist/runtime/utils.js +3 -2
- package/dist/shared/scripts.DLRgvHQg.mjs +288 -0
- package/dist/stats.d.mts +39 -0
- package/dist/stats.d.ts +39 -0
- package/dist/stats.mjs +711 -0
- package/dist/types.d.mts +1 -1
- package/package.json +48 -41
- package/dist/client/_nuxt/Bdf7Qtwg.js +0 -1
- package/dist/client/_nuxt/CoyZWCgl.js +0 -162
- package/dist/client/_nuxt/Ds1k3yKJ.js +0 -1
- package/dist/client/_nuxt/builds/meta/62574f80-71d4-4f9e-8b96-145c85230d99.json +0 -1
- package/dist/client/_nuxt/entry.BjfcJo5q.css +0 -1
- package/dist/client/_nuxt/error-404.D45Vtjcx.css +0 -1
- 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)
|
|
59
|
-
|
|
60
|
-
if (options?.
|
|
61
|
-
|
|
62
|
-
if (options?.
|
|
63
|
-
|
|
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(
|
|
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,
|
|
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
|
-
|
|
51
|
-
|
|
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 { 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)
|
|
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())
|
|
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
|
});
|
|
@@ -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: {
|
|
@@ -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,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)
|
|
8
|
+
get: (k: string) => any;
|
|
9
9
|
loaded: 0 | 1;
|
|
10
10
|
loading: 0 | 1;
|
|
11
|
-
ready(f: () => void)
|
|
12
|
-
scan()
|
|
13
|
-
setConfig(config: YT.PlayerOptions)
|
|
14
|
-
subscribe<EventName extends keyof YT.Events>(event: EventName, listener: YT.Events[EventName], context?: any)
|
|
15
|
-
unsubscribe<EventName extends keyof YT.Events>(event: EventName, listener: YT.Events[EventName], context?: any)
|
|
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,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,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(/&/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,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(/&/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,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(/&/g, "&"))}`
|
|
76
|
+
).replace(
|
|
77
|
+
/https:\/\/static\.cdninstagram\.com[^"'\s),]+/g,
|
|
78
|
+
(m) => `/api/_scripts/instagram-embed-asset?url=${encodeURIComponent(m.replace(/&/g, "&"))}`
|
|
79
|
+
).replace(
|
|
80
|
+
/https:\/\/lookaside\.instagram\.com[^"'\s),]+/g,
|
|
81
|
+
(m) => `/api/_scripts/instagram-embed-image?url=${encodeURIComponent(m.replace(/&/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;
|