Gate analytics and cache public API requests

This commit is contained in:
2569718930@qq.com
2026-04-06 13:58:11 +08:00
parent 9be12ad1d7
commit 08d7308486
14 changed files with 114 additions and 309 deletions
@@ -5,8 +5,14 @@ import {
} from "@/lib/backend-auth";
const API_BASE = process.env.POLYWEATHER_API_BASE_URL;
const ANALYTICS_ENABLED =
process.env.NEXT_PUBLIC_POLYWEATHER_APP_ANALYTICS === "true";
export async function POST(req: NextRequest) {
if (!ANALYTICS_ENABLED) {
return new NextResponse(null, { status: 204 });
}
if (!API_BASE) {
return NextResponse.json(
{ error: "POLYWEATHER_API_BASE_URL is not configured" },
+8 -3
View File
@@ -18,10 +18,15 @@ export async function GET(req: NextRequest) {
}
try {
const auth = await buildBackendRequestHeaders(req);
const res = await fetch(`${API_BASE}/api/cities`, {
const auth = await buildBackendRequestHeaders(req, {
includeSupabaseIdentity: false,
});
const fetchOptions = {
headers: auth.headers,
cache: "no-store",
next: { revalidate: 300 },
} as const;
const res = await fetch(`${API_BASE}/api/cities`, {
...fetchOptions,
});
if (!res.ok) {
const raw = await res.text();
+3 -1
View File
@@ -23,7 +23,9 @@ export async function GET(
const url = `${API_BASE}/api/city/${encodeURIComponent(name)}?force_refresh=${forceRefresh}`;
try {
const auth = await buildBackendRequestHeaders(req);
const auth = await buildBackendRequestHeaders(req, {
includeSupabaseIdentity: false,
});
const res = await fetch(url, {
headers: auth.headers,
cache: "no-store",
+14 -3
View File
@@ -25,10 +25,21 @@ export async function GET(
const url = `${API_BASE}/api/city/${encodeURIComponent(name)}/summary?force_refresh=${forceRefresh}`;
try {
const auth = await buildBackendRequestHeaders(req);
const auth = await buildBackendRequestHeaders(req, {
includeSupabaseIdentity: false,
});
const fetchOptions =
bypassCache
? {
headers: auth.headers,
cache: "no-store" as const,
}
: {
headers: auth.headers,
next: { revalidate: 20 },
};
const res = await fetch(url, {
headers: auth.headers,
cache: "no-store",
...fetchOptions,
});
if (!res.ok) {
const raw = await res.text();
+3 -1
View File
@@ -15,7 +15,9 @@ export async function GET(req: NextRequest) {
}
try {
const auth = await buildBackendRequestHeaders(req);
const auth = await buildBackendRequestHeaders(req, {
includeSupabaseIdentity: false,
});
const res = await fetch(`${API_BASE}/healthz`, {
headers: auth.headers,
cache: "no-store",
+5 -2
View File
@@ -24,9 +24,12 @@ export async function GET(
try {
const auth = await buildBackendRequestHeaders(req);
const res = await fetch(url, {
const fetchOptions = {
headers: auth.headers,
cache: "no-store",
next: { revalidate: 60 },
} as const;
const res = await fetch(url, {
...fetchOptions,
});
if (!res.ok) {
const raw = await res.text();
+17
View File
@@ -5,6 +5,9 @@ import {
recordVitalsSample,
} from "@/lib/vitals-store";
const WEB_VITALS_ENABLED =
process.env.NEXT_PUBLIC_POLYWEATHER_WEB_VITALS === "true";
type VitalsPayload = {
id?: string;
metric?: string;
@@ -15,6 +18,10 @@ type VitalsPayload = {
};
export async function POST(request: Request) {
if (!WEB_VITALS_ENABLED) {
return new NextResponse(null, { status: 204 });
}
try {
const payload = (await request.json()) as VitalsPayload;
const metric = normalizeMetricName(payload.metric);
@@ -56,6 +63,16 @@ export async function POST(request: Request) {
}
export async function GET(request: Request) {
if (!WEB_VITALS_ENABLED) {
return NextResponse.json({
ok: true,
disabled: true,
generatedAt: Date.now(),
sampleCount: 0,
routes: {},
});
}
const { searchParams } = new URL(request.url);
const targetRoute = String(searchParams.get("route") || "").trim();
const summary = getVitalsSummary();
+1 -5
View File
@@ -1,5 +1,4 @@
import type { Metadata } from "next";
import { Analytics } from "@vercel/analytics/react";
import "./globals.css";
export const metadata: Metadata = {
@@ -31,10 +30,7 @@ export default function RootLayout({
rel="stylesheet"
/>
</head>
<body className="min-h-screen font-sans antialiased">
{children}
<Analytics />
</body>
<body className="min-h-screen font-sans antialiased">{children}</body>
</html>
);
}
@@ -4,10 +4,16 @@ import { usePathname } from "next/navigation";
import { useReportWebVitals } from "next/web-vitals";
const TRACKED_METRICS = new Set(["INP", "LCP", "FCP"]);
const WEB_VITALS_ENABLED =
process.env.NEXT_PUBLIC_POLYWEATHER_WEB_VITALS === "true";
export function WebVitalsReporter() {
const pathname = usePathname();
if (!WEB_VITALS_ENABLED) {
return null;
}
useReportWebVitals((metric) => {
if (!TRACKED_METRICS.has(metric.name)) {
return;
+3
View File
@@ -88,6 +88,8 @@ function getMarketScanCacheKey(cityName: string, targetDate?: string | null) {
const SELECTED_CITY_STORAGE_KEY = "polyWeather_selected_city_v1";
const BACKGROUND_SUMMARY_REFRESH_MS = 30_000;
const EAGER_CITY_SUMMARIES_ENABLED =
process.env.NEXT_PUBLIC_POLYWEATHER_EAGER_CITY_SUMMARIES === "true";
export function DashboardStoreProvider({
children,
@@ -392,6 +394,7 @@ export function DashboardStoreProvider({
]);
useEffect(() => {
if (!EAGER_CITY_SUMMARIES_ENABLED) return;
if (!cities.length) return;
const queue = cities
+4 -1
View File
@@ -1,5 +1,8 @@
"use client";
const ANALYTICS_ENABLED =
process.env.NEXT_PUBLIC_POLYWEATHER_APP_ANALYTICS === "true";
type TrackableAnalyticsEvent =
| "signup_completed"
| "dashboard_active"
@@ -68,7 +71,7 @@ export function trackAppEvent(
eventType: TrackableAnalyticsEvent,
payload: Record<string, unknown> = {},
) {
if (!isClient()) return;
if (!isClient() || !ANALYTICS_ENABLED) return;
const body = {
event_type: eventType,
client_id: getAnalyticsClientId() || undefined,
+7 -1
View File
@@ -11,6 +11,10 @@ type HeaderBuildResult = {
response: NextResponse | null;
};
type HeaderBuildOptions = {
includeSupabaseIdentity?: boolean;
};
function extractBearerToken(headerValue: string | null) {
if (!headerValue) return "";
const parts = headerValue.trim().split(/\s+/);
@@ -22,6 +26,7 @@ function extractBearerToken(headerValue: string | null) {
export async function buildBackendRequestHeaders(
request: NextRequest,
options?: HeaderBuildOptions,
): Promise<HeaderBuildResult> {
const headers = new Headers({
Accept: "application/json",
@@ -32,7 +37,8 @@ export async function buildBackendRequestHeaders(
}
const incomingAuth = extractBearerToken(request.headers.get("authorization"));
if (hasSupabaseServerEnv()) {
const includeSupabaseIdentity = options?.includeSupabaseIdentity !== false;
if (hasSupabaseServerEnv() && includeSupabaseIdentity) {
const passthroughResponse = new NextResponse(null, { status: 200 });
const supabase = createSupabaseRouteClient(request, passthroughResponse);
const {
+37 -290
View File
@@ -11,8 +11,6 @@
"@radix-ui/react-slot": "^1.1.2",
"@supabase/ssr": "^0.5.2",
"@supabase/supabase-js": "^2.57.2",
"@vercel/analytics": "^1.6.1",
"@vercel/speed-insights": "^2.0.0",
"@walletconnect/ethereum-provider": "^2.23.8",
"chart.js": "^4.5.1",
"class-variance-authority": "^0.7.1",
@@ -2054,47 +2052,6 @@
}
}
},
"node_modules/@solana/kit": {
"version": "5.5.1",
"resolved": "https://registry.npmmirror.com/@solana/kit/-/kit-5.5.1.tgz",
"integrity": "sha512-irKUGiV2yRoyf+4eGQ/ZeCRxa43yjFEL1DUI5B0DkcfZw3cr0VJtVJnrG8OtVF01vT0OUfYOcUn6zJW5TROHvQ==",
"optional": true,
"dependencies": {
"@solana/accounts": "5.5.1",
"@solana/addresses": "5.5.1",
"@solana/codecs": "5.5.1",
"@solana/errors": "5.5.1",
"@solana/functional": "5.5.1",
"@solana/instruction-plans": "5.5.1",
"@solana/instructions": "5.5.1",
"@solana/keys": "5.5.1",
"@solana/offchain-messages": "5.5.1",
"@solana/plugin-core": "5.5.1",
"@solana/programs": "5.5.1",
"@solana/rpc": "5.5.1",
"@solana/rpc-api": "5.5.1",
"@solana/rpc-parsed-types": "5.5.1",
"@solana/rpc-spec-types": "5.5.1",
"@solana/rpc-subscriptions": "5.5.1",
"@solana/rpc-types": "5.5.1",
"@solana/signers": "5.5.1",
"@solana/sysvars": "5.5.1",
"@solana/transaction-confirmation": "5.5.1",
"@solana/transaction-messages": "5.5.1",
"@solana/transactions": "5.5.1"
},
"engines": {
"node": ">=20.18.0"
},
"peerDependencies": {
"typescript": "^5.0.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/@solana/nominal-types": {
"version": "5.5.1",
"resolved": "https://registry.npmmirror.com/@solana/nominal-types/-/nominal-types-5.5.1.tgz",
@@ -2846,6 +2803,7 @@
"version": "2.99.1",
"resolved": "https://registry.npmmirror.com/@supabase/supabase-js/-/supabase-js-2.99.1.tgz",
"integrity": "sha512-5MRoYD9ffXq8F6a036dm65YoSHisC3by/d22mauKE99Vrwf792KxYIIr/iqCX7E4hkuugbPZ5EGYHTB7MKy6Vg==",
"peer": true,
"dependencies": {
"@supabase/auth-js": "2.99.1",
"@supabase/functions-js": "2.99.1",
@@ -2918,6 +2876,7 @@
"resolved": "https://registry.npmmirror.com/@types/react/-/react-19.2.14.tgz",
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
"devOptional": true,
"peer": true,
"dependencies": {
"csstype": "^3.2.2"
}
@@ -2977,80 +2936,6 @@
"@types/node": "*"
}
},
"node_modules/@vercel/analytics": {
"version": "1.6.1",
"resolved": "https://registry.npmmirror.com/@vercel/analytics/-/analytics-1.6.1.tgz",
"integrity": "sha512-oH9He/bEM+6oKlv3chWuOOcp8Y6fo6/PSro8hEkgCW3pu9/OiCXiUpRUogDh3Fs3LH2sosDrx8CxeOLBEE+afg==",
"peerDependencies": {
"@remix-run/react": "^2",
"@sveltejs/kit": "^1 || ^2",
"next": ">= 13",
"react": "^18 || ^19 || ^19.0.0-rc",
"svelte": ">= 4",
"vue": "^3",
"vue-router": "^4"
},
"peerDependenciesMeta": {
"@remix-run/react": {
"optional": true
},
"@sveltejs/kit": {
"optional": true
},
"next": {
"optional": true
},
"react": {
"optional": true
},
"svelte": {
"optional": true
},
"vue": {
"optional": true
},
"vue-router": {
"optional": true
}
}
},
"node_modules/@vercel/speed-insights": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/@vercel/speed-insights/-/speed-insights-2.0.0.tgz",
"integrity": "sha512-jwkNcrTeafWxjmWq4AHBaptSqZiJkYU5adLC9QBSqeim0GcqDMgN5Ievh8OG1rJ6W3A4l1oiP7qr9CWxGuzu3w==",
"peerDependencies": {
"@sveltejs/kit": "^1 || ^2",
"next": ">= 13",
"nuxt": ">= 3",
"react": "^18 || ^19 || ^19.0.0-rc",
"svelte": ">= 4",
"vue": "^3",
"vue-router": "^4"
},
"peerDependenciesMeta": {
"@sveltejs/kit": {
"optional": true
},
"next": {
"optional": true
},
"nuxt": {
"optional": true
},
"react": {
"optional": true
},
"svelte": {
"optional": true
},
"vue": {
"optional": true
},
"vue-router": {
"optional": true
}
}
},
"node_modules/@wallet-standard/base": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/@wallet-standard/base/-/base-1.1.0.tgz",
@@ -3209,20 +3094,6 @@
"ws": "^7.5.1"
}
},
"node_modules/@walletconnect/jsonrpc-ws-connection/node_modules/utf-8-validate": {
"version": "5.0.10",
"resolved": "https://registry.npmmirror.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz",
"integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==",
"hasInstallScript": true,
"optional": true,
"peer": true,
"dependencies": {
"node-gyp-build": "^4.3.0"
},
"engines": {
"node": ">=6.14.2"
}
},
"node_modules/@walletconnect/jsonrpc-ws-connection/node_modules/ws": {
"version": "7.5.10",
"resolved": "https://registry.npmmirror.com/ws/-/ws-7.5.10.tgz",
@@ -3651,17 +3522,6 @@
"postcss": "^8.1.0"
}
},
"node_modules/axios": {
"version": "1.13.6",
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.13.6.tgz",
"integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==",
"optional": true,
"dependencies": {
"follow-redirects": "^1.15.11",
"form-data": "^4.0.5",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/axios-retry": {
"version": "4.5.0",
"resolved": "https://registry.npmmirror.com/axios-retry/-/axios-retry-4.5.0.tgz",
@@ -3805,6 +3665,7 @@
"url": "https://github.com/sponsors/ai"
}
],
"peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
@@ -3850,19 +3711,6 @@
"ieee754": "^1.2.1"
}
},
"node_modules/bufferutil": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/bufferutil/-/bufferutil-4.1.0.tgz",
"integrity": "sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==",
"hasInstallScript": true,
"optional": true,
"dependencies": {
"node-gyp-build": "^4.3.0"
},
"engines": {
"node": ">=6.14.2"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
@@ -4783,20 +4631,6 @@
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"optional": true
},
"node_modules/jayson/node_modules/utf-8-validate": {
"version": "5.0.10",
"resolved": "https://registry.npmmirror.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz",
"integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==",
"hasInstallScript": true,
"optional": true,
"peer": true,
"dependencies": {
"node-gyp-build": "^4.3.0"
},
"engines": {
"node": ">=6.14.2"
}
},
"node_modules/jayson/node_modules/ws": {
"version": "7.5.10",
"resolved": "https://registry.npmmirror.com/ws/-/ws-7.5.10.tgz",
@@ -4823,6 +4657,7 @@
"resolved": "https://registry.npmmirror.com/jiti/-/jiti-1.21.7.tgz",
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
"dev": true,
"peer": true,
"bin": {
"jiti": "bin/jiti.js"
}
@@ -4850,7 +4685,8 @@
"node_modules/leaflet": {
"version": "1.9.4",
"resolved": "https://registry.npmmirror.com/leaflet/-/leaflet-1.9.4.tgz",
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA=="
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==",
"peer": true
},
"node_modules/lilconfig": {
"version": "3.1.3",
@@ -5384,6 +5220,7 @@
"url": "https://github.com/sponsors/ai"
}
],
"peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -5608,6 +5445,7 @@
"version": "19.2.4",
"resolved": "https://registry.npmmirror.com/react/-/react-19.2.4.tgz",
"integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -5616,6 +5454,7 @@
"version": "19.2.4",
"resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-19.2.4.tgz",
"integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==",
"peer": true,
"dependencies": {
"scheduler": "^0.27.0"
},
@@ -6118,6 +5957,7 @@
"resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"peer": true,
"engines": {
"node": ">=12"
},
@@ -6158,6 +5998,7 @@
"resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"devOptional": true,
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -6550,6 +6391,7 @@
"version": "8.19.0",
"resolved": "https://registry.npmmirror.com/ws/-/ws-8.19.0.tgz",
"integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
"peer": true,
"engines": {
"node": ">=10.0.0"
},
@@ -6604,15 +6446,6 @@
"node": ">=6"
}
},
"node_modules/zod": {
"version": "3.25.76",
"resolved": "https://registry.npmmirror.com/zod/-/zod-3.25.76.tgz",
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
"optional": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/zustand": {
"version": "5.0.3",
"resolved": "https://registry.npmmirror.com/zustand/-/zustand-5.0.3.tgz",
@@ -7883,8 +7716,7 @@
"requires": {}
},
"@solana/instruction-plans": {
"version": "5.5.1",
"resolved": "https://registry.npmmirror.com/@solana/instruction-plans/-/instruction-plans-5.5.1.tgz",
"version": "https://registry.npmmirror.com/@solana/instruction-plans/-/instruction-plans-5.5.1.tgz",
"integrity": "sha512-7z3CB7YMcFKuVvgcnNY8bY6IsZ8LG61Iytbz7HpNVGX2u1RthOs1tRW8luTzSG1MPL0Ox7afyAVMYeFqSPHnaQ==",
"optional": true,
"requires": {
@@ -7919,36 +7751,6 @@
"@solana/nominal-types": "5.5.1"
}
},
"@solana/kit": {
"version": "5.5.1",
"resolved": "https://registry.npmmirror.com/@solana/kit/-/kit-5.5.1.tgz",
"integrity": "sha512-irKUGiV2yRoyf+4eGQ/ZeCRxa43yjFEL1DUI5B0DkcfZw3cr0VJtVJnrG8OtVF01vT0OUfYOcUn6zJW5TROHvQ==",
"optional": true,
"requires": {
"@solana/accounts": "5.5.1",
"@solana/addresses": "5.5.1",
"@solana/codecs": "5.5.1",
"@solana/errors": "5.5.1",
"@solana/functional": "5.5.1",
"@solana/instruction-plans": "5.5.1",
"@solana/instructions": "5.5.1",
"@solana/keys": "5.5.1",
"@solana/offchain-messages": "5.5.1",
"@solana/plugin-core": "5.5.1",
"@solana/programs": "5.5.1",
"@solana/rpc": "5.5.1",
"@solana/rpc-api": "5.5.1",
"@solana/rpc-parsed-types": "5.5.1",
"@solana/rpc-spec-types": "5.5.1",
"@solana/rpc-subscriptions": "5.5.1",
"@solana/rpc-types": "5.5.1",
"@solana/signers": "5.5.1",
"@solana/sysvars": "5.5.1",
"@solana/transaction-confirmation": "5.5.1",
"@solana/transaction-messages": "5.5.1",
"@solana/transactions": "5.5.1"
}
},
"@solana/nominal-types": {
"version": "5.5.1",
"resolved": "https://registry.npmmirror.com/@solana/nominal-types/-/nominal-types-5.5.1.tgz",
@@ -7986,15 +7788,13 @@
}
},
"@solana/plugin-core": {
"version": "5.5.1",
"resolved": "https://registry.npmmirror.com/@solana/plugin-core/-/plugin-core-5.5.1.tgz",
"version": "https://registry.npmmirror.com/@solana/plugin-core/-/plugin-core-5.5.1.tgz",
"integrity": "sha512-VUZl30lDQFJeiSyNfzU1EjYt2QZvoBFKEwjn1lilUJw7KgqD5z7mbV7diJhT+dLFs36i0OsjXvq5kSygn8YJ3A==",
"optional": true,
"requires": {}
},
"@solana/programs": {
"version": "5.5.1",
"resolved": "https://registry.npmmirror.com/@solana/programs/-/programs-5.5.1.tgz",
"version": "https://registry.npmmirror.com/@solana/programs/-/programs-5.5.1.tgz",
"integrity": "sha512-7U9kn0Jsx1NuBLn5HRTFYh78MV4XN145Yc3WP/q5BlqAVNlMoU9coG5IUTJIG847TUqC1lRto3Dnpwm6T4YRpA==",
"optional": true,
"requires": {
@@ -8176,8 +7976,7 @@
}
},
"@solana/signers": {
"version": "5.5.1",
"resolved": "https://registry.npmmirror.com/@solana/signers/-/signers-5.5.1.tgz",
"version": "https://registry.npmmirror.com/@solana/signers/-/signers-5.5.1.tgz",
"integrity": "sha512-FY0IVaBT2kCAze55vEieR6hag4coqcuJ31Aw3hqRH7mv6sV8oqwuJmUrx+uFwOp1gwd5OEAzlv6N4hOOple4sQ==",
"optional": true,
"requires": {
@@ -8202,8 +8001,7 @@
}
},
"@solana/sysvars": {
"version": "5.5.1",
"resolved": "https://registry.npmmirror.com/@solana/sysvars/-/sysvars-5.5.1.tgz",
"version": "https://registry.npmmirror.com/@solana/sysvars/-/sysvars-5.5.1.tgz",
"integrity": "sha512-k3Quq87Mm+geGUu1GWv6knPk0ALsfY6EKSJGw9xUJDHzY/RkYSBnh0RiOrUhtFm2TDNjOailg8/m0VHmi3reFA==",
"optional": true,
"requires": {
@@ -8214,8 +8012,7 @@
}
},
"@solana/transaction-confirmation": {
"version": "5.5.1",
"resolved": "https://registry.npmmirror.com/@solana/transaction-confirmation/-/transaction-confirmation-5.5.1.tgz",
"version": "https://registry.npmmirror.com/@solana/transaction-confirmation/-/transaction-confirmation-5.5.1.tgz",
"integrity": "sha512-j4mKlYPHEyu+OD7MBt3jRoX4ScFgkhZC6H65on4Fux6LMScgivPJlwnKoZMnsgxFgWds0pl+BYzSiALDsXlYtw==",
"optional": true,
"requires": {
@@ -8403,6 +8200,7 @@
"version": "2.99.1",
"resolved": "https://registry.npmmirror.com/@supabase/supabase-js/-/supabase-js-2.99.1.tgz",
"integrity": "sha512-5MRoYD9ffXq8F6a036dm65YoSHisC3by/d22mauKE99Vrwf792KxYIIr/iqCX7E4hkuugbPZ5EGYHTB7MKy6Vg==",
"peer": true,
"requires": {
"@supabase/auth-js": "2.99.1",
"@supabase/functions-js": "2.99.1",
@@ -8472,6 +8270,7 @@
"resolved": "https://registry.npmmirror.com/@types/react/-/react-19.2.14.tgz",
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
"devOptional": true,
"peer": true,
"requires": {
"csstype": "^3.2.2"
}
@@ -8529,18 +8328,6 @@
"@types/node": "*"
}
},
"@vercel/analytics": {
"version": "1.6.1",
"resolved": "https://registry.npmmirror.com/@vercel/analytics/-/analytics-1.6.1.tgz",
"integrity": "sha512-oH9He/bEM+6oKlv3chWuOOcp8Y6fo6/PSro8hEkgCW3pu9/OiCXiUpRUogDh3Fs3LH2sosDrx8CxeOLBEE+afg==",
"requires": {}
},
"@vercel/speed-insights": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/@vercel/speed-insights/-/speed-insights-2.0.0.tgz",
"integrity": "sha512-jwkNcrTeafWxjmWq4AHBaptSqZiJkYU5adLC9QBSqeim0GcqDMgN5Ievh8OG1rJ6W3A4l1oiP7qr9CWxGuzu3w==",
"requires": {}
},
"@wallet-standard/base": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/@wallet-standard/base/-/base-1.1.0.tgz",
@@ -8696,16 +8483,6 @@
"ws": "^7.5.1"
},
"dependencies": {
"utf-8-validate": {
"version": "5.0.10",
"resolved": "https://registry.npmmirror.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz",
"integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==",
"optional": true,
"peer": true,
"requires": {
"node-gyp-build": "^4.3.0"
}
},
"ws": {
"version": "7.5.10",
"resolved": "https://registry.npmmirror.com/ws/-/ws-7.5.10.tgz",
@@ -9021,17 +8798,6 @@
"postcss-value-parser": "^4.2.0"
}
},
"axios": {
"version": "1.13.6",
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.13.6.tgz",
"integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==",
"optional": true,
"requires": {
"follow-redirects": "^1.15.11",
"form-data": "^4.0.5",
"proxy-from-env": "^1.1.0"
}
},
"axios-retry": {
"version": "4.5.0",
"resolved": "https://registry.npmmirror.com/axios-retry/-/axios-retry-4.5.0.tgz",
@@ -9124,6 +8890,7 @@
"resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.28.1.tgz",
"integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
"dev": true,
"peer": true,
"requires": {
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
@@ -9149,15 +8916,6 @@
"ieee754": "^1.2.1"
}
},
"bufferutil": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/bufferutil/-/bufferutil-4.1.0.tgz",
"integrity": "sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==",
"optional": true,
"requires": {
"node-gyp-build": "^4.3.0"
}
},
"call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
@@ -9557,14 +9315,12 @@
}
},
"follow-redirects": {
"version": "1.15.11",
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz",
"version": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz",
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
"optional": true
},
"form-data": {
"version": "4.0.5",
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.5.tgz",
"version": "https://registry.npmmirror.com/form-data/-/form-data-4.0.5.tgz",
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
"optional": true,
"requires": {
@@ -9821,16 +9577,6 @@
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"optional": true
},
"utf-8-validate": {
"version": "5.0.10",
"resolved": "https://registry.npmmirror.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz",
"integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==",
"optional": true,
"peer": true,
"requires": {
"node-gyp-build": "^4.3.0"
}
},
"ws": {
"version": "7.5.10",
"resolved": "https://registry.npmmirror.com/ws/-/ws-7.5.10.tgz",
@@ -9844,7 +9590,8 @@
"version": "1.21.7",
"resolved": "https://registry.npmmirror.com/jiti/-/jiti-1.21.7.tgz",
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
"dev": true
"dev": true,
"peer": true
},
"jose": {
"version": "6.2.1",
@@ -9866,7 +9613,8 @@
"leaflet": {
"version": "1.9.4",
"resolved": "https://registry.npmmirror.com/leaflet/-/leaflet-1.9.4.tgz",
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA=="
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==",
"peer": true
},
"lilconfig": {
"version": "3.1.3",
@@ -10221,6 +9969,7 @@
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.8.tgz",
"integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==",
"dev": true,
"peer": true,
"requires": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -10298,8 +10047,7 @@
"integrity": "sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q=="
},
"proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"version": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"optional": true
},
@@ -10333,12 +10081,14 @@
"react": {
"version": "19.2.4",
"resolved": "https://registry.npmmirror.com/react/-/react-19.2.4.tgz",
"integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="
"integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==",
"peer": true
},
"react-dom": {
"version": "19.2.4",
"resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-19.2.4.tgz",
"integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==",
"peer": true,
"requires": {
"scheduler": "^0.27.0"
}
@@ -10681,7 +10431,8 @@
"version": "4.0.3",
"resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true
"dev": true,
"peer": true
}
}
},
@@ -10714,7 +10465,8 @@
"version": "5.9.3",
"resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"devOptional": true
"devOptional": true,
"peer": true
},
"ufo": {
"version": "1.6.3",
@@ -10898,6 +10650,7 @@
"version": "8.19.0",
"resolved": "https://registry.npmmirror.com/ws/-/ws-8.19.0.tgz",
"integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
"peer": true,
"requires": {}
},
"y18n": {
@@ -10932,12 +10685,6 @@
"decamelize": "^1.2.0"
}
},
"zod": {
"version": "3.25.76",
"resolved": "https://registry.npmmirror.com/zod/-/zod-3.25.76.tgz",
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
"optional": true
},
"zustand": {
"version": "5.0.3",
"resolved": "https://registry.npmmirror.com/zustand/-/zustand-5.0.3.tgz",
-2
View File
@@ -12,8 +12,6 @@
"@radix-ui/react-slot": "^1.1.2",
"@supabase/ssr": "^0.5.2",
"@supabase/supabase-js": "^2.57.2",
"@vercel/analytics": "^1.6.1",
"@vercel/speed-insights": "^2.0.0",
"@walletconnect/ethereum-provider": "^2.23.8",
"chart.js": "^4.5.1",
"class-variance-authority": "^0.7.1",