@nuxt/scripts 1.0.0-rc.9 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/devtools-client/200.html +1 -1
- package/dist/devtools-client/404.html +1 -1
- package/dist/devtools-client/_nuxt/{Cxq4HLPL.js → BjIIVRlr.js} +1 -1
- package/dist/devtools-client/_nuxt/{BBS9G2Kb.js → C3h_qg0j.js} +1 -1
- package/dist/devtools-client/_nuxt/{DCBsJT4N.js → CKrGhxlH.js} +1 -1
- package/dist/devtools-client/_nuxt/DD1eKorn.js +1 -0
- package/dist/devtools-client/_nuxt/{B4uHpJPz.js → DTVoxnk-.js} +1 -1
- package/dist/devtools-client/_nuxt/{DvZScWzI.js → TnW0ti1s.js} +1 -1
- package/dist/devtools-client/_nuxt/UTyLw2F_.js +188 -0
- package/dist/devtools-client/_nuxt/builds/latest.json +1 -1
- package/dist/devtools-client/_nuxt/builds/meta/8eda1fb3-23bc-456f-8373-7e503f9580ec.json +1 -0
- package/dist/devtools-client/_nuxt/{entry.BwpOBArY.css → entry.BKkVrcJj.css} +1 -1
- package/dist/devtools-client/_nuxt/error-404.Rdq9GpXu.css +1 -0
- package/dist/devtools-client/_nuxt/error-500.BPHNCR4E.css +1 -0
- package/dist/devtools-client/_nuxt/index.DZD1lwyI.css +1 -0
- package/dist/devtools-client/docs/index.html +1 -1
- package/dist/devtools-client/first-party/index.html +1 -1
- package/dist/devtools-client/index.html +1 -1
- package/dist/devtools-client/registry/index.html +1 -1
- package/dist/module.d.mts +18 -2
- package/dist/module.d.ts +18 -2
- package/dist/module.json +1 -1
- package/dist/module.mjs +81 -9
- package/dist/registry.mjs +10 -6
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue +1 -2
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue +3 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsStaticMap.vue +6 -2
- package/dist/runtime/components/ScriptBlueskyEmbed.d.vue.ts +0 -1
- package/dist/runtime/components/ScriptBlueskyEmbed.vue +12 -10
- package/dist/runtime/components/ScriptBlueskyEmbed.vue.d.ts +0 -1
- package/dist/runtime/components/ScriptInstagramEmbed.vue +3 -1
- package/dist/runtime/components/ScriptXEmbed.d.vue.ts +0 -1
- package/dist/runtime/components/ScriptXEmbed.vue +11 -9
- package/dist/runtime/components/ScriptXEmbed.vue.d.ts +0 -1
- package/dist/runtime/composables/useScript.js +17 -6
- package/dist/runtime/composables/useScriptProxyToken.d.ts +12 -0
- package/dist/runtime/composables/useScriptProxyToken.js +4 -0
- package/dist/runtime/composables/useScriptProxyUrl.d.ts +12 -0
- package/dist/runtime/composables/useScriptProxyUrl.js +27 -0
- package/dist/runtime/plugins/proxy-token.server.d.ts +10 -0
- package/dist/runtime/plugins/proxy-token.server.js +17 -0
- package/dist/runtime/registry/bing-uet.d.ts +6 -2
- package/dist/runtime/registry/bing-uet.js +13 -1
- package/dist/runtime/registry/bluesky-embed.d.ts +0 -4
- package/dist/runtime/registry/bluesky-embed.js +0 -4
- package/dist/runtime/registry/clarity.d.ts +6 -2
- package/dist/runtime/registry/clarity.js +12 -1
- package/dist/runtime/registry/google-analytics.d.ts +6 -2
- package/dist/runtime/registry/google-analytics.js +12 -1
- package/dist/runtime/registry/google-tag-manager.d.ts +6 -2
- package/dist/runtime/registry/google-tag-manager.js +10 -1
- package/dist/runtime/registry/gravatar.js +10 -13
- package/dist/runtime/registry/matomo-analytics.d.ts +9 -3
- package/dist/runtime/registry/matomo-analytics.js +28 -1
- package/dist/runtime/registry/meta-pixel.d.ts +8 -2
- package/dist/runtime/registry/meta-pixel.js +10 -1
- package/dist/runtime/registry/mixpanel-analytics.d.ts +12 -2
- package/dist/runtime/registry/mixpanel-analytics.js +16 -4
- package/dist/runtime/registry/posthog.d.ts +8 -2
- package/dist/runtime/registry/posthog.js +15 -4
- package/dist/runtime/registry/schemas.d.ts +65 -0
- package/dist/runtime/registry/schemas.js +75 -8
- package/dist/runtime/registry/tiktok-pixel.d.ts +16 -2
- package/dist/runtime/registry/tiktok-pixel.js +22 -1
- package/dist/runtime/registry/x-embed.d.ts +0 -4
- package/dist/runtime/registry/x-embed.js +0 -4
- package/dist/runtime/server/bluesky-embed-image.d.ts +1 -1
- package/dist/runtime/server/bluesky-embed.d.ts +1 -15
- package/dist/runtime/server/bluesky-embed.js +22 -4
- package/dist/runtime/server/google-maps-geocode-proxy.js +8 -5
- package/dist/runtime/server/google-static-maps-proxy.d.ts +1 -1
- package/dist/runtime/server/google-static-maps-proxy.js +13 -8
- package/dist/runtime/server/gravatar-proxy.d.ts +1 -1
- package/dist/runtime/server/gravatar-proxy.js +6 -7
- package/dist/runtime/server/instagram-embed-asset.d.ts +1 -1
- package/dist/runtime/server/instagram-embed-image.d.ts +1 -1
- package/dist/runtime/server/instagram-embed.js +22 -10
- package/dist/runtime/server/utils/cached-upstream.d.ts +55 -0
- package/dist/runtime/server/utils/cached-upstream.js +65 -0
- package/dist/runtime/server/utils/embed-rewriters.d.ts +19 -0
- package/dist/runtime/server/utils/embed-rewriters.js +41 -0
- package/dist/runtime/server/utils/image-proxy.d.ts +3 -1
- package/dist/runtime/server/utils/image-proxy.js +8 -6
- package/dist/runtime/server/utils/instagram-embed.d.ts +4 -4
- package/dist/runtime/server/utils/instagram-embed.js +10 -9
- package/dist/runtime/server/utils/proxy-url.d.ts +9 -0
- package/dist/runtime/server/utils/proxy-url.js +21 -0
- package/dist/runtime/server/utils/sign-constants.d.ts +16 -0
- package/dist/runtime/server/utils/sign-constants.js +5 -0
- package/dist/runtime/server/utils/sign.d.ts +2 -10
- package/dist/runtime/server/utils/sign.js +8 -5
- package/dist/runtime/server/utils/withSigning.js +3 -2
- package/dist/runtime/server/vercel-insights-sink.d.ts +2 -0
- package/dist/runtime/server/vercel-insights-sink.js +5 -0
- package/dist/runtime/server/x-embed-image.d.ts +1 -1
- package/dist/runtime/server/x-embed.js +20 -2
- package/dist/runtime/types.d.ts +28 -1
- package/dist/types-source.mjs +104 -11
- package/dist/types.d.mts +1 -1
- package/package.json +3 -3
- package/dist/devtools-client/_nuxt/CQR4zIAm.js +0 -1
- package/dist/devtools-client/_nuxt/DTxy5P8N.js +0 -188
- package/dist/devtools-client/_nuxt/builds/meta/bd58b869-1eb5-4c50-871c-707f9b71e8f9.json +0 -1
- package/dist/devtools-client/_nuxt/error-404.d44aGwWI.css +0 -1
- package/dist/devtools-client/_nuxt/error-500.NthMfIEt.css +0 -1
- package/dist/devtools-client/_nuxt/index.CA-OpSj0.css +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useRegistryScript } from "../utils.js";
|
|
2
2
|
import { MixpanelAnalyticsOptions } from "./schemas.js";
|
|
3
3
|
export { MixpanelAnalyticsOptions };
|
|
4
|
-
const methods = ["track", "identify", "reset", "register"];
|
|
4
|
+
const methods = ["track", "identify", "reset", "register", "opt_in_tracking", "opt_out_tracking"];
|
|
5
5
|
const peopleMethods = ["set"];
|
|
6
6
|
export function useScriptMixpanelAnalytics(_options) {
|
|
7
|
-
|
|
7
|
+
const instance = useRegistryScript("mixpanelAnalytics", (options) => {
|
|
8
8
|
return {
|
|
9
9
|
scriptInput: {
|
|
10
10
|
src: "https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js"
|
|
@@ -38,9 +38,21 @@ export function useScriptMixpanelAnalytics(_options) {
|
|
|
38
38
|
mp._i.push([token, config, name]);
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
|
-
if (options?.token)
|
|
42
|
-
|
|
41
|
+
if (options?.token) {
|
|
42
|
+
const optOutByDefault = options?.defaultConsent === "opt-out";
|
|
43
|
+
mp.init(options.token, optOutByDefault ? { opt_out_tracking_by_default: true } : void 0);
|
|
44
|
+
if (options?.defaultConsent === "opt-in") {
|
|
45
|
+
mp.opt_in_tracking?.();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
43
48
|
}
|
|
44
49
|
};
|
|
45
50
|
}, _options);
|
|
51
|
+
if (import.meta.client && !instance.consent) {
|
|
52
|
+
instance.consent = {
|
|
53
|
+
optIn: () => instance.proxy.mixpanel.opt_in_tracking?.(),
|
|
54
|
+
optOut: () => instance.proxy.mixpanel.opt_out_tracking?.()
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return instance;
|
|
46
58
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RegistryScriptInput } from '#nuxt-scripts/types';
|
|
1
|
+
import type { RegistryScriptInput, UseScriptContext } from '#nuxt-scripts/types';
|
|
2
2
|
import type { PostHog, PostHogConfig } from 'posthog-js';
|
|
3
3
|
import { PostHogOptions } from './schemas.js';
|
|
4
4
|
export { PostHogOptions };
|
|
@@ -22,4 +22,10 @@ declare global {
|
|
|
22
22
|
}[];
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
export
|
|
25
|
+
export interface PostHogConsent {
|
|
26
|
+
/** Call `posthog.opt_in_capturing()`. */
|
|
27
|
+
optIn: () => void;
|
|
28
|
+
/** Call `posthog.opt_out_capturing()`. For boot-time opt-out, use `defaultConsent: 'opt-out'` instead. */
|
|
29
|
+
optOut: () => void;
|
|
30
|
+
}
|
|
31
|
+
export declare function useScriptPostHog<T extends PostHogApi>(_options?: PostHogInput): UseScriptContext<T, PostHogConsent>;
|
|
@@ -3,7 +3,7 @@ import { useRegistryScript } from "../utils.js";
|
|
|
3
3
|
import { PostHogOptions } from "./schemas.js";
|
|
4
4
|
export { PostHogOptions };
|
|
5
5
|
export function useScriptPostHog(_options) {
|
|
6
|
-
|
|
6
|
+
const instance = useRegistryScript("posthog", (options) => {
|
|
7
7
|
return {
|
|
8
8
|
scriptMode: "npm",
|
|
9
9
|
// Use NPM mode - no external script tag
|
|
@@ -55,13 +55,17 @@ export function useScriptPostHog(_options) {
|
|
|
55
55
|
config.capture_pageleave = options.capturePageleave;
|
|
56
56
|
if (typeof options?.disableSessionRecording === "boolean")
|
|
57
57
|
config.disable_session_recording = options.disableSessionRecording;
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
if (options?.defaultConsent === "opt-out")
|
|
59
|
+
config.opt_out_capturing_by_default = true;
|
|
60
|
+
const instance2 = posthog.init(options.apiKey, config);
|
|
61
|
+
if (!instance2) {
|
|
60
62
|
logger.error("PostHog init returned undefined - initialization failed");
|
|
61
63
|
delete window._posthogQueue;
|
|
62
64
|
return void 0;
|
|
63
65
|
}
|
|
64
|
-
window.posthog =
|
|
66
|
+
window.posthog = instance2;
|
|
67
|
+
if (options?.defaultConsent === "opt-in")
|
|
68
|
+
instance2.opt_in_capturing?.();
|
|
65
69
|
if (window._posthogQueue && window._posthogQueue.length > 0) {
|
|
66
70
|
window._posthogQueue.forEach((q) => window.posthog[q.prop]?.(...q.args));
|
|
67
71
|
delete window._posthogQueue;
|
|
@@ -76,4 +80,11 @@ export function useScriptPostHog(_options) {
|
|
|
76
80
|
}
|
|
77
81
|
};
|
|
78
82
|
}, _options);
|
|
83
|
+
if (import.meta.client && !instance.consent) {
|
|
84
|
+
instance.consent = {
|
|
85
|
+
optIn: () => instance.proxy.posthog?.opt_in_capturing?.(),
|
|
86
|
+
optOut: () => instance.proxy.posthog?.opt_out_capturing?.()
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return instance;
|
|
79
90
|
}
|
|
@@ -21,6 +21,13 @@ export declare const ClarityOptions: import("valibot").ObjectSchema<{
|
|
|
21
21
|
* @see https://learn.microsoft.com/en-us/clarity/setup-clarity
|
|
22
22
|
*/
|
|
23
23
|
readonly id: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 10, undefined>]>;
|
|
24
|
+
/**
|
|
25
|
+
* Default consent state applied before Clarity starts.
|
|
26
|
+
* - `boolean` - enable / disable cookies.
|
|
27
|
+
* - `Record<string, string>` - advanced consent vector (see Clarity docs).
|
|
28
|
+
* @see https://learn.microsoft.com/en-us/clarity/setup-and-installation/cookie-consent
|
|
29
|
+
*/
|
|
30
|
+
readonly defaultConsent: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").BooleanSchema<undefined>, import("valibot").RecordSchema<import("valibot").StringSchema<undefined>, import("valibot").StringSchema<undefined>, undefined>], undefined>, undefined>;
|
|
24
31
|
}, undefined>;
|
|
25
32
|
export declare const CloudflareWebAnalyticsOptions: import("valibot").ObjectSchema<{
|
|
26
33
|
/**
|
|
@@ -267,6 +274,21 @@ export declare const GoogleAnalyticsOptions: import("valibot").ObjectSchema<{
|
|
|
267
274
|
* @see https://developers.google.com/analytics/devguides/collection/gtagjs/setting-up-gtag#rename_the_data_layer
|
|
268
275
|
*/
|
|
269
276
|
readonly l: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
277
|
+
/**
|
|
278
|
+
* Default GCMv2 consent state fired as `gtag('consent', 'default', ...)` before `gtag('js', ...)`.
|
|
279
|
+
* @see https://developers.google.com/tag-platform/security/guides/consent
|
|
280
|
+
*/
|
|
281
|
+
readonly defaultConsent: import("valibot").OptionalSchema<import("valibot").ObjectSchema<{
|
|
282
|
+
readonly ad_storage: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>], undefined>, undefined>;
|
|
283
|
+
readonly ad_user_data: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>], undefined>, undefined>;
|
|
284
|
+
readonly ad_personalization: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>], undefined>, undefined>;
|
|
285
|
+
readonly analytics_storage: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>], undefined>, undefined>;
|
|
286
|
+
readonly functionality_storage: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>], undefined>, undefined>;
|
|
287
|
+
readonly personalization_storage: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>], undefined>, undefined>;
|
|
288
|
+
readonly security_storage: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>], undefined>, undefined>;
|
|
289
|
+
readonly wait_for_update: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
|
|
290
|
+
readonly region: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").StringSchema<undefined>, undefined>, undefined>;
|
|
291
|
+
}, undefined>, undefined>;
|
|
270
292
|
}, undefined>;
|
|
271
293
|
export declare const GoogleMapsOptions: import("valibot").ObjectSchema<{
|
|
272
294
|
/**
|
|
@@ -533,6 +555,14 @@ export declare const MatomoAnalyticsOptions: import("valibot").ObjectSchema<{
|
|
|
533
555
|
* @default true
|
|
534
556
|
*/
|
|
535
557
|
readonly watch: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
|
|
558
|
+
/**
|
|
559
|
+
* Default tracking-consent state applied BEFORE the tracker is initialised.
|
|
560
|
+
* - `'required'` — call `requireConsent` without granting (user must opt in later).
|
|
561
|
+
* - `'given'` — call `requireConsent` then `setConsentGiven`.
|
|
562
|
+
* - `'not-required'` — no consent gating (default Matomo behaviour).
|
|
563
|
+
* @see https://developer.matomo.org/guides/tracking-consent
|
|
564
|
+
*/
|
|
565
|
+
readonly defaultConsent: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"required", undefined>, import("valibot").LiteralSchema<"given", undefined>, import("valibot").LiteralSchema<"not-required", undefined>], undefined>, undefined>;
|
|
536
566
|
}, undefined>;
|
|
537
567
|
export declare const MetaPixelOptions: import("valibot").ObjectSchema<{
|
|
538
568
|
/**
|
|
@@ -540,6 +570,12 @@ export declare const MetaPixelOptions: import("valibot").ObjectSchema<{
|
|
|
540
570
|
* @see https://developers.facebook.com/docs/meta-pixel/get-started
|
|
541
571
|
*/
|
|
542
572
|
readonly id: import("valibot").UnionSchema<[import("valibot").StringSchema<undefined>, import("valibot").NumberSchema<undefined>], undefined>;
|
|
573
|
+
/**
|
|
574
|
+
* Default consent state. `'granted'` fires `fbq('consent', 'grant')`,
|
|
575
|
+
* `'denied'` fires `fbq('consent', 'revoke')`, both called before `fbq('init', id)`.
|
|
576
|
+
* @see https://www.facebook.com/business/help/1151321516677370
|
|
577
|
+
*/
|
|
578
|
+
readonly defaultConsent: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>], undefined>, undefined>;
|
|
543
579
|
}, undefined>;
|
|
544
580
|
export declare const NpmOptions: import("valibot").ObjectSchema<{
|
|
545
581
|
/**
|
|
@@ -630,6 +666,13 @@ export declare const PostHogOptions: import("valibot").ObjectSchema<{
|
|
|
630
666
|
* @see https://posthog.com/docs/libraries/js#config
|
|
631
667
|
*/
|
|
632
668
|
readonly config: import("valibot").OptionalSchema<import("valibot").RecordSchema<import("valibot").StringSchema<undefined>, import("valibot").AnySchema, undefined>, undefined>;
|
|
669
|
+
/**
|
|
670
|
+
* Default capture-consent state for PostHog.
|
|
671
|
+
* - `'opt-out'`: passed as `opt_out_capturing_by_default: true` to `posthog.init`, so capturing is suppressed from the first event.
|
|
672
|
+
* - `'opt-in'`: applied after `posthog.init` via `posthog.opt_in_capturing()` on the returned instance.
|
|
673
|
+
* @see https://posthog.com/docs/privacy/opting-out
|
|
674
|
+
*/
|
|
675
|
+
readonly defaultConsent: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"opt-in", undefined>, import("valibot").LiteralSchema<"opt-out", undefined>], undefined>, undefined>;
|
|
633
676
|
}, undefined>;
|
|
634
677
|
export declare const RedditPixelOptions: import("valibot").ObjectSchema<{
|
|
635
678
|
/**
|
|
@@ -703,6 +746,13 @@ export declare const MixpanelAnalyticsOptions: import("valibot").ObjectSchema<{
|
|
|
703
746
|
* @see https://docs.mixpanel.com/docs/tracking-methods/sdks/javascript#1-initialize-the-library
|
|
704
747
|
*/
|
|
705
748
|
readonly token: import("valibot").StringSchema<undefined>;
|
|
749
|
+
/**
|
|
750
|
+
* Default tracking-consent state for Mixpanel.
|
|
751
|
+
* - `'opt-out'`: passed as `opt_out_tracking_by_default: true` to `mixpanel.init`, so tracking is suppressed from the first call.
|
|
752
|
+
* - `'opt-in'`: queued via `mixpanel.push(['opt_in_tracking'])` so the real SDK runs it immediately after load.
|
|
753
|
+
* @see https://docs.mixpanel.com/docs/privacy/opt-out-of-tracking
|
|
754
|
+
*/
|
|
755
|
+
readonly defaultConsent: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"opt-in", undefined>, import("valibot").LiteralSchema<"opt-out", undefined>], undefined>, undefined>;
|
|
706
756
|
}, undefined>;
|
|
707
757
|
export declare const BingUetOptions: import("valibot").ObjectSchema<{
|
|
708
758
|
/**
|
|
@@ -715,6 +765,13 @@ export declare const BingUetOptions: import("valibot").ObjectSchema<{
|
|
|
715
765
|
* @default true
|
|
716
766
|
*/
|
|
717
767
|
readonly enableAutoSpaTracking: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
|
|
768
|
+
/**
|
|
769
|
+
* Default consent state fired as `uetq.push('consent', 'default', ...)` before UET init.
|
|
770
|
+
* @see https://help.ads.microsoft.com/#apex/ads/en/60119/1-500
|
|
771
|
+
*/
|
|
772
|
+
readonly defaultConsent: import("valibot").OptionalSchema<import("valibot").ObjectSchema<{
|
|
773
|
+
readonly ad_storage: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>], undefined>, undefined>;
|
|
774
|
+
}, undefined>, undefined>;
|
|
718
775
|
}, undefined>;
|
|
719
776
|
export declare const SegmentOptions: import("valibot").ObjectSchema<{
|
|
720
777
|
/**
|
|
@@ -857,6 +914,14 @@ export declare const TikTokPixelOptions: import("valibot").ObjectSchema<{
|
|
|
857
914
|
* @default true
|
|
858
915
|
*/
|
|
859
916
|
readonly trackPageView: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
|
|
917
|
+
/**
|
|
918
|
+
* Default consent state, applied before `ttq('init', id)`.
|
|
919
|
+
* - `'granted'` fires `ttq.grantConsent()`
|
|
920
|
+
* - `'denied'` fires `ttq.revokeConsent()`
|
|
921
|
+
* - `'hold'` fires `ttq.holdConsent()` to defer until an explicit update
|
|
922
|
+
* @see https://business-api.tiktok.com/portal/docs?id=1739585600931842
|
|
923
|
+
*/
|
|
924
|
+
readonly defaultConsent: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"granted", undefined>, import("valibot").LiteralSchema<"denied", undefined>, import("valibot").LiteralSchema<"hold", undefined>], undefined>, undefined>;
|
|
860
925
|
}, undefined>;
|
|
861
926
|
export declare const UmamiAnalyticsOptions: import("valibot").ObjectSchema<{
|
|
862
927
|
/**
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import { any, array, boolean, custom, literal, minLength, number, object, optional, pipe, record, string, union } from "valibot";
|
|
2
|
+
const consentCategoryValue = union([literal("granted"), literal("denied")]);
|
|
3
|
+
const gcmConsentState = object({
|
|
4
|
+
ad_storage: optional(consentCategoryValue),
|
|
5
|
+
ad_user_data: optional(consentCategoryValue),
|
|
6
|
+
ad_personalization: optional(consentCategoryValue),
|
|
7
|
+
analytics_storage: optional(consentCategoryValue),
|
|
8
|
+
functionality_storage: optional(consentCategoryValue),
|
|
9
|
+
personalization_storage: optional(consentCategoryValue),
|
|
10
|
+
security_storage: optional(consentCategoryValue),
|
|
11
|
+
wait_for_update: optional(number()),
|
|
12
|
+
region: optional(array(string()))
|
|
13
|
+
});
|
|
2
14
|
export const BlueskyEmbedOptions = object({
|
|
3
15
|
/**
|
|
4
16
|
* The Bluesky post URL to embed.
|
|
@@ -21,7 +33,14 @@ export const ClarityOptions = object({
|
|
|
21
33
|
* The Clarity token.
|
|
22
34
|
* @see https://learn.microsoft.com/en-us/clarity/setup-clarity
|
|
23
35
|
*/
|
|
24
|
-
id: pipe(string(), minLength(10))
|
|
36
|
+
id: pipe(string(), minLength(10)),
|
|
37
|
+
/**
|
|
38
|
+
* Default consent state applied before Clarity starts.
|
|
39
|
+
* - `boolean` - enable / disable cookies.
|
|
40
|
+
* - `Record<string, string>` - advanced consent vector (see Clarity docs).
|
|
41
|
+
* @see https://learn.microsoft.com/en-us/clarity/setup-and-installation/cookie-consent
|
|
42
|
+
*/
|
|
43
|
+
defaultConsent: optional(union([boolean(), record(string(), string())]))
|
|
25
44
|
});
|
|
26
45
|
export const CloudflareWebAnalyticsOptions = object({
|
|
27
46
|
/**
|
|
@@ -264,7 +283,12 @@ export const GoogleAnalyticsOptions = object({
|
|
|
264
283
|
* @default 'dataLayer'
|
|
265
284
|
* @see https://developers.google.com/analytics/devguides/collection/gtagjs/setting-up-gtag#rename_the_data_layer
|
|
266
285
|
*/
|
|
267
|
-
l: optional(string())
|
|
286
|
+
l: optional(string()),
|
|
287
|
+
/**
|
|
288
|
+
* Default GCMv2 consent state fired as `gtag('consent', 'default', ...)` before `gtag('js', ...)`.
|
|
289
|
+
* @see https://developers.google.com/tag-platform/security/guides/consent
|
|
290
|
+
*/
|
|
291
|
+
defaultConsent: optional(gcmConsentState)
|
|
268
292
|
});
|
|
269
293
|
export const GoogleMapsOptions = object({
|
|
270
294
|
/**
|
|
@@ -527,14 +551,28 @@ export const MatomoAnalyticsOptions = object({
|
|
|
527
551
|
* Automatically track page views on route change.
|
|
528
552
|
* @default true
|
|
529
553
|
*/
|
|
530
|
-
watch: optional(boolean())
|
|
554
|
+
watch: optional(boolean()),
|
|
555
|
+
/**
|
|
556
|
+
* Default tracking-consent state applied BEFORE the tracker is initialised.
|
|
557
|
+
* - `'required'` — call `requireConsent` without granting (user must opt in later).
|
|
558
|
+
* - `'given'` — call `requireConsent` then `setConsentGiven`.
|
|
559
|
+
* - `'not-required'` — no consent gating (default Matomo behaviour).
|
|
560
|
+
* @see https://developer.matomo.org/guides/tracking-consent
|
|
561
|
+
*/
|
|
562
|
+
defaultConsent: optional(union([literal("required"), literal("given"), literal("not-required")]))
|
|
531
563
|
});
|
|
532
564
|
export const MetaPixelOptions = object({
|
|
533
565
|
/**
|
|
534
566
|
* Your Meta (Facebook) Pixel ID.
|
|
535
567
|
* @see https://developers.facebook.com/docs/meta-pixel/get-started
|
|
536
568
|
*/
|
|
537
|
-
id: union([string(), number()])
|
|
569
|
+
id: union([string(), number()]),
|
|
570
|
+
/**
|
|
571
|
+
* Default consent state. `'granted'` fires `fbq('consent', 'grant')`,
|
|
572
|
+
* `'denied'` fires `fbq('consent', 'revoke')`, both called before `fbq('init', id)`.
|
|
573
|
+
* @see https://www.facebook.com/business/help/1151321516677370
|
|
574
|
+
*/
|
|
575
|
+
defaultConsent: optional(union([literal("granted"), literal("denied")]))
|
|
538
576
|
});
|
|
539
577
|
export const NpmOptions = object({
|
|
540
578
|
/**
|
|
@@ -627,7 +665,14 @@ export const PostHogOptions = object({
|
|
|
627
665
|
* Additional PostHog configuration options passed directly to `posthog.init()`.
|
|
628
666
|
* @see https://posthog.com/docs/libraries/js#config
|
|
629
667
|
*/
|
|
630
|
-
config: optional(record(string(), any()))
|
|
668
|
+
config: optional(record(string(), any())),
|
|
669
|
+
/**
|
|
670
|
+
* Default capture-consent state for PostHog.
|
|
671
|
+
* - `'opt-out'`: passed as `opt_out_capturing_by_default: true` to `posthog.init`, so capturing is suppressed from the first event.
|
|
672
|
+
* - `'opt-in'`: applied after `posthog.init` via `posthog.opt_in_capturing()` on the returned instance.
|
|
673
|
+
* @see https://posthog.com/docs/privacy/opting-out
|
|
674
|
+
*/
|
|
675
|
+
defaultConsent: optional(union([literal("opt-in"), literal("opt-out")]))
|
|
631
676
|
});
|
|
632
677
|
export const RedditPixelOptions = object({
|
|
633
678
|
/**
|
|
@@ -700,7 +745,14 @@ export const MixpanelAnalyticsOptions = object({
|
|
|
700
745
|
* Your Mixpanel project token.
|
|
701
746
|
* @see https://docs.mixpanel.com/docs/tracking-methods/sdks/javascript#1-initialize-the-library
|
|
702
747
|
*/
|
|
703
|
-
token: string()
|
|
748
|
+
token: string(),
|
|
749
|
+
/**
|
|
750
|
+
* Default tracking-consent state for Mixpanel.
|
|
751
|
+
* - `'opt-out'`: passed as `opt_out_tracking_by_default: true` to `mixpanel.init`, so tracking is suppressed from the first call.
|
|
752
|
+
* - `'opt-in'`: queued via `mixpanel.push(['opt_in_tracking'])` so the real SDK runs it immediately after load.
|
|
753
|
+
* @see https://docs.mixpanel.com/docs/privacy/opt-out-of-tracking
|
|
754
|
+
*/
|
|
755
|
+
defaultConsent: optional(union([literal("opt-in"), literal("opt-out")]))
|
|
704
756
|
});
|
|
705
757
|
export const BingUetOptions = object({
|
|
706
758
|
/**
|
|
@@ -712,7 +764,14 @@ export const BingUetOptions = object({
|
|
|
712
764
|
* Enable automatic SPA page tracking.
|
|
713
765
|
* @default true
|
|
714
766
|
*/
|
|
715
|
-
enableAutoSpaTracking: optional(boolean())
|
|
767
|
+
enableAutoSpaTracking: optional(boolean()),
|
|
768
|
+
/**
|
|
769
|
+
* Default consent state fired as `uetq.push('consent', 'default', ...)` before UET init.
|
|
770
|
+
* @see https://help.ads.microsoft.com/#apex/ads/en/60119/1-500
|
|
771
|
+
*/
|
|
772
|
+
defaultConsent: optional(object({
|
|
773
|
+
ad_storage: optional(consentCategoryValue)
|
|
774
|
+
}))
|
|
716
775
|
});
|
|
717
776
|
export const SegmentOptions = object({
|
|
718
777
|
/**
|
|
@@ -807,7 +866,15 @@ export const TikTokPixelOptions = object({
|
|
|
807
866
|
* Whether to automatically track a page view on initialization.
|
|
808
867
|
* @default true
|
|
809
868
|
*/
|
|
810
|
-
trackPageView: optional(boolean())
|
|
869
|
+
trackPageView: optional(boolean()),
|
|
870
|
+
/**
|
|
871
|
+
* Default consent state, applied before `ttq('init', id)`.
|
|
872
|
+
* - `'granted'` fires `ttq.grantConsent()`
|
|
873
|
+
* - `'denied'` fires `ttq.revokeConsent()`
|
|
874
|
+
* - `'hold'` fires `ttq.holdConsent()` to defer until an explicit update
|
|
875
|
+
* @see https://business-api.tiktok.com/portal/docs?id=1739585600931842
|
|
876
|
+
*/
|
|
877
|
+
defaultConsent: optional(union([literal("granted"), literal("denied"), literal("hold")]))
|
|
811
878
|
});
|
|
812
879
|
export const UmamiAnalyticsOptions = object({
|
|
813
880
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RegistryScriptInput } from '#nuxt-scripts/types';
|
|
1
|
+
import type { RegistryScriptInput, UseScriptContext } from '#nuxt-scripts/types';
|
|
2
2
|
import { TikTokPixelOptions } from './schemas.js';
|
|
3
3
|
type StandardEvents = 'ViewContent' | 'ClickButton' | 'Search' | 'AddToWishlist' | 'AddToCart' | 'InitiateCheckout' | 'AddPaymentInfo' | 'CompletePayment' | 'PlaceAnOrder' | 'Contact' | 'Download' | 'SubmitForm' | 'CompleteRegistration' | 'Subscribe';
|
|
4
4
|
interface EventProperties {
|
|
@@ -29,6 +29,12 @@ export interface TikTokPixelApi {
|
|
|
29
29
|
push: TtqFns;
|
|
30
30
|
loaded: boolean;
|
|
31
31
|
queue: any[];
|
|
32
|
+
/** Opt user in to tracking. Queued before the script loads; live once `events.js` binds. */
|
|
33
|
+
grantConsent: () => void;
|
|
34
|
+
/** Opt user out of tracking. Queued before the script loads; live once `events.js` binds. */
|
|
35
|
+
revokeConsent: () => void;
|
|
36
|
+
/** Defer consent until an explicit grant/revoke. Queued before the script loads; live once `events.js` binds. */
|
|
37
|
+
holdConsent: () => void;
|
|
32
38
|
};
|
|
33
39
|
}
|
|
34
40
|
declare global {
|
|
@@ -38,4 +44,12 @@ declare global {
|
|
|
38
44
|
}
|
|
39
45
|
export { TikTokPixelOptions };
|
|
40
46
|
export type TikTokPixelInput = RegistryScriptInput<typeof TikTokPixelOptions, true, false>;
|
|
41
|
-
export
|
|
47
|
+
export interface TikTokPixelConsent {
|
|
48
|
+
/** Call `ttq.grantConsent()`. */
|
|
49
|
+
grant: () => void;
|
|
50
|
+
/** Call `ttq.revokeConsent()`. */
|
|
51
|
+
revoke: () => void;
|
|
52
|
+
/** Call `ttq.holdConsent()` to defer the decision. */
|
|
53
|
+
hold: () => void;
|
|
54
|
+
}
|
|
55
|
+
export declare function useScriptTikTokPixel<T extends TikTokPixelApi>(_options?: TikTokPixelInput): UseScriptContext<T, TikTokPixelConsent>;
|
|
@@ -3,7 +3,7 @@ import { useRegistryScript } from "../utils.js";
|
|
|
3
3
|
import { TikTokPixelOptions } from "./schemas.js";
|
|
4
4
|
export { TikTokPixelOptions };
|
|
5
5
|
export function useScriptTikTokPixel(_options) {
|
|
6
|
-
|
|
6
|
+
const instance = useRegistryScript("tiktokPixel", (options) => ({
|
|
7
7
|
scriptInput: {
|
|
8
8
|
src: withQuery("https://analytics.tiktok.com/i18n/pixel/events.js", {
|
|
9
9
|
sdkid: options?.id,
|
|
@@ -29,6 +29,19 @@ export function useScriptTikTokPixel(_options) {
|
|
|
29
29
|
ttq.push = ttq;
|
|
30
30
|
ttq.loaded = true;
|
|
31
31
|
ttq.queue = [];
|
|
32
|
+
const consentMethods = ["grantConsent", "revokeConsent", "holdConsent"];
|
|
33
|
+
for (const name of consentMethods) {
|
|
34
|
+
;
|
|
35
|
+
ttq[name] = function(...params) {
|
|
36
|
+
ttq.queue.push([name, ...params]);
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (options?.defaultConsent === "granted")
|
|
40
|
+
ttq.grantConsent();
|
|
41
|
+
else if (options?.defaultConsent === "denied")
|
|
42
|
+
ttq.revokeConsent();
|
|
43
|
+
else if (options?.defaultConsent === "hold")
|
|
44
|
+
ttq.holdConsent();
|
|
32
45
|
if (options?.id) {
|
|
33
46
|
ttq("init", options.id);
|
|
34
47
|
if (options?.trackPageView !== false) {
|
|
@@ -37,4 +50,12 @@ export function useScriptTikTokPixel(_options) {
|
|
|
37
50
|
}
|
|
38
51
|
}
|
|
39
52
|
}), _options);
|
|
53
|
+
if (import.meta.client && !instance.consent) {
|
|
54
|
+
instance.consent = {
|
|
55
|
+
grant: () => instance.proxy.ttq.grantConsent(),
|
|
56
|
+
revoke: () => instance.proxy.ttq.revokeConsent(),
|
|
57
|
+
hold: () => instance.proxy.ttq.holdConsent()
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return instance;
|
|
40
61
|
}
|
|
@@ -49,10 +49,6 @@ export interface XEmbedTweetData {
|
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
51
|
export type XEmbedInput = RegistryScriptInput<typeof XEmbedOptions, false, false>;
|
|
52
|
-
/**
|
|
53
|
-
* Proxy an X/Twitter image URL through the server
|
|
54
|
-
*/
|
|
55
|
-
export declare function proxyXImageUrl(url: string, proxyEndpoint?: string): string;
|
|
56
52
|
/**
|
|
57
53
|
* Format a tweet date for display
|
|
58
54
|
*/
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { XEmbedOptions } from "./schemas.js";
|
|
2
2
|
export { XEmbedOptions };
|
|
3
|
-
export function proxyXImageUrl(url, proxyEndpoint = "/_scripts/embed/x-image") {
|
|
4
|
-
const separator = proxyEndpoint.includes("?") ? "&" : "?";
|
|
5
|
-
return `${proxyEndpoint}${separator}url=${encodeURIComponent(url)}`;
|
|
6
|
-
}
|
|
7
3
|
export function formatTweetDate(dateString) {
|
|
8
4
|
const date = new Date(dateString);
|
|
9
5
|
const time = date.toLocaleString("en-US", {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<
|
|
1
|
+
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<Buffer<ArrayBufferLike>>>;
|
|
2
2
|
export default _default;
|
|
@@ -1,16 +1,2 @@
|
|
|
1
|
-
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<
|
|
2
|
-
uri: string;
|
|
3
|
-
cid: string;
|
|
4
|
-
author: Record<string, any>;
|
|
5
|
-
record: Record<string, any>;
|
|
6
|
-
embed?: Record<string, any>;
|
|
7
|
-
likeCount: number;
|
|
8
|
-
repostCount: number;
|
|
9
|
-
replyCount: number;
|
|
10
|
-
quoteCount: number;
|
|
11
|
-
indexedAt: string;
|
|
12
|
-
labels: Array<{
|
|
13
|
-
val: string;
|
|
14
|
-
}>;
|
|
15
|
-
}>>;
|
|
1
|
+
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<Record<string, any>>>;
|
|
16
2
|
export default _default;
|
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import { createError, defineEventHandler, getQuery, setHeader } from "h3";
|
|
2
|
-
import {
|
|
2
|
+
import { useRuntimeConfig } from "nitropack/runtime";
|
|
3
|
+
import { createCachedJsonFetch } from "./utils/cached-upstream.js";
|
|
4
|
+
import { rewriteBlueskyPostImages } from "./utils/embed-rewriters.js";
|
|
3
5
|
import { withSigning } from "./utils/withSigning.js";
|
|
4
6
|
const BSKY_POST_URL_RE = /^https:\/\/bsky\.app\/profile\/([^/]+)\/post\/([^/?]+)$/;
|
|
7
|
+
const EMBED_BSKY_SUFFIX_RE = /\/embed\/bluesky$/;
|
|
8
|
+
const cachedProfileFetch = createCachedJsonFetch(
|
|
9
|
+
"nuxt-scripts-bsky-profile",
|
|
10
|
+
86400,
|
|
11
|
+
(url) => url
|
|
12
|
+
);
|
|
13
|
+
const cachedPostFetch = createCachedJsonFetch(
|
|
14
|
+
"nuxt-scripts-bsky-post",
|
|
15
|
+
600,
|
|
16
|
+
(url) => url
|
|
17
|
+
);
|
|
5
18
|
export default withSigning(defineEventHandler(async (event) => {
|
|
6
19
|
const query = getQuery(event);
|
|
7
20
|
const postUrl = query.url;
|
|
@@ -21,7 +34,7 @@ export default withSigning(defineEventHandler(async (event) => {
|
|
|
21
34
|
const [, actor, rkey] = match;
|
|
22
35
|
let did = actor;
|
|
23
36
|
if (!actor.startsWith("did:")) {
|
|
24
|
-
const profile = await
|
|
37
|
+
const profile = await cachedProfileFetch(
|
|
25
38
|
`https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=${encodeURIComponent(actor)}`
|
|
26
39
|
).catch((error) => {
|
|
27
40
|
throw createError({
|
|
@@ -32,7 +45,7 @@ export default withSigning(defineEventHandler(async (event) => {
|
|
|
32
45
|
did = profile.did;
|
|
33
46
|
}
|
|
34
47
|
const uri = `at://${did}/app.bsky.feed.post/${rkey}`;
|
|
35
|
-
const response = await
|
|
48
|
+
const response = await cachedPostFetch(
|
|
36
49
|
`https://public.api.bsky.app/xrpc/app.bsky.feed.getPostThread?uri=${encodeURIComponent(uri)}&depth=0&parentHeight=0`
|
|
37
50
|
).catch((error) => {
|
|
38
51
|
throw createError({
|
|
@@ -46,7 +59,7 @@ export default withSigning(defineEventHandler(async (event) => {
|
|
|
46
59
|
statusMessage: "Post not found"
|
|
47
60
|
});
|
|
48
61
|
}
|
|
49
|
-
const post = response.thread.post;
|
|
62
|
+
const post = structuredClone(response.thread.post);
|
|
50
63
|
const hasOptOut = post.labels?.some((l) => l.val === "!no-unauthenticated") || post.author?.labels?.some((l) => l.val === "!no-unauthenticated");
|
|
51
64
|
if (hasOptOut) {
|
|
52
65
|
throw createError({
|
|
@@ -54,6 +67,11 @@ export default withSigning(defineEventHandler(async (event) => {
|
|
|
54
67
|
statusMessage: "Author has opted out of external embedding"
|
|
55
68
|
});
|
|
56
69
|
}
|
|
70
|
+
const handlerPath = event.path?.split("?")[0] || "";
|
|
71
|
+
const prefix = handlerPath.replace(EMBED_BSKY_SUFFIX_RE, "") || "/_scripts";
|
|
72
|
+
const imagePath = `${prefix}/embed/bluesky-image`;
|
|
73
|
+
const secret = useRuntimeConfig(event)["nuxt-scripts"]?.proxySecret;
|
|
74
|
+
rewriteBlueskyPostImages(post, imagePath, secret);
|
|
57
75
|
setHeader(event, "Content-Type", "application/json");
|
|
58
76
|
setHeader(event, "Cache-Control", "public, max-age=600, s-maxage=600");
|
|
59
77
|
return post;
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { createError, defineEventHandler, getQuery, setHeader } from "h3";
|
|
2
2
|
import { useRuntimeConfig } from "nitropack/runtime";
|
|
3
|
-
import { $fetch } from "ofetch";
|
|
4
3
|
import { withQuery } from "ufo";
|
|
4
|
+
import { createCachedJsonFetch } from "./utils/cached-upstream.js";
|
|
5
5
|
import { withSigning } from "./utils/withSigning.js";
|
|
6
|
+
const cachedGeocodeFetch = createCachedJsonFetch(
|
|
7
|
+
"nuxt-scripts-geocode",
|
|
8
|
+
2592e3,
|
|
9
|
+
(url) => url
|
|
10
|
+
);
|
|
6
11
|
export default withSigning(defineEventHandler(async (event) => {
|
|
7
12
|
const runtimeConfig = useRuntimeConfig();
|
|
8
13
|
const privateConfig = runtimeConfig["nuxt-scripts"]?.googleMapsGeocodeProxy;
|
|
@@ -19,10 +24,8 @@ export default withSigning(defineEventHandler(async (event) => {
|
|
|
19
24
|
...safeQuery,
|
|
20
25
|
key: apiKey
|
|
21
26
|
});
|
|
22
|
-
const data = await
|
|
23
|
-
headers: {
|
|
24
|
-
"User-Agent": "Nuxt Scripts Google Geocode Proxy"
|
|
25
|
-
}
|
|
27
|
+
const data = await cachedGeocodeFetch(geocodeUrl, {
|
|
28
|
+
headers: { "User-Agent": "Nuxt Scripts Google Geocode Proxy" }
|
|
26
29
|
}).catch((error) => {
|
|
27
30
|
throw createError({
|
|
28
31
|
statusCode: error.statusCode || 500,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<
|
|
1
|
+
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<Buffer<ArrayBufferLike>>>;
|
|
2
2
|
export default _default;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { createError, defineEventHandler, getQuery, setHeader } from "h3";
|
|
2
2
|
import { useRuntimeConfig } from "nitropack/runtime";
|
|
3
|
-
import { $fetch } from "ofetch";
|
|
4
3
|
import { withQuery } from "ufo";
|
|
4
|
+
import { createCachedBinaryFetch } from "./utils/cached-upstream.js";
|
|
5
|
+
import { PAGE_TOKEN_PARAM, PAGE_TOKEN_TS_PARAM, SIG_PARAM } from "./utils/sign-constants.js";
|
|
5
6
|
import { withSigning } from "./utils/withSigning.js";
|
|
7
|
+
const cachedMapFetch = createCachedBinaryFetch("nuxt-scripts-static-map", 604800);
|
|
8
|
+
const STRIP_PARAMS = /* @__PURE__ */ new Set([SIG_PARAM, PAGE_TOKEN_PARAM, PAGE_TOKEN_TS_PARAM, "key"]);
|
|
6
9
|
export default withSigning(defineEventHandler(async (event) => {
|
|
7
10
|
const runtimeConfig = useRuntimeConfig();
|
|
8
11
|
const publicConfig = runtimeConfig.public["nuxt-scripts"]?.googleStaticMapsProxy;
|
|
@@ -21,15 +24,17 @@ export default withSigning(defineEventHandler(async (event) => {
|
|
|
21
24
|
});
|
|
22
25
|
}
|
|
23
26
|
const query = getQuery(event);
|
|
24
|
-
const
|
|
27
|
+
const safeQuery = {};
|
|
28
|
+
for (const [k, v] of Object.entries(query)) {
|
|
29
|
+
if (!STRIP_PARAMS.has(k))
|
|
30
|
+
safeQuery[k] = v;
|
|
31
|
+
}
|
|
25
32
|
const googleMapsUrl = withQuery("https://maps.googleapis.com/maps/api/staticmap", {
|
|
26
33
|
...safeQuery,
|
|
27
34
|
key: apiKey
|
|
28
35
|
});
|
|
29
|
-
const
|
|
30
|
-
headers: {
|
|
31
|
-
"User-Agent": "Nuxt Scripts Google Static Maps Proxy"
|
|
32
|
-
}
|
|
36
|
+
const result = await cachedMapFetch(googleMapsUrl, {
|
|
37
|
+
headers: { "User-Agent": "Nuxt Scripts Google Static Maps Proxy" }
|
|
33
38
|
}).catch((error) => {
|
|
34
39
|
throw createError({
|
|
35
40
|
statusCode: error.statusCode || 500,
|
|
@@ -37,8 +42,8 @@ export default withSigning(defineEventHandler(async (event) => {
|
|
|
37
42
|
});
|
|
38
43
|
});
|
|
39
44
|
const cacheMaxAge = publicConfig.cacheMaxAge || 3600;
|
|
40
|
-
setHeader(event, "Content-Type",
|
|
45
|
+
setHeader(event, "Content-Type", result.contentType || "image/png");
|
|
41
46
|
setHeader(event, "Cache-Control", `public, max-age=${cacheMaxAge}, s-maxage=${cacheMaxAge}`);
|
|
42
47
|
setHeader(event, "Vary", "Accept-Encoding");
|
|
43
|
-
return
|
|
48
|
+
return result.body;
|
|
44
49
|
}));
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<
|
|
1
|
+
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<Buffer<ArrayBufferLike>>>;
|
|
2
2
|
export default _default;
|