From a17d893811f81054343c36d236eb623b91641027 Mon Sep 17 00:00:00 2001 From: MananTank Date: Mon, 31 Mar 2025 18:38:58 +0000 Subject: [PATCH] [TOOL-3873] Fix pageview tracking in dashboard, Add posthog to playground (#6595) --- .../src/app/components/root-providers.tsx | 22 ------- apps/dashboard/src/app/layout.tsx | 10 +++- .../components/wallets/PosthogIdentifier.tsx | 23 ++++---- apps/dashboard/src/lib/posthog/Posthog.tsx | 28 +++++++++ .../src/lib/posthog/PosthogHeadSetup.tsx | 10 ++++ .../src/lib/posthog/PosthogPageView.tsx | 34 +++++++++++ apps/playground-web/next.config.mjs | 2 +- apps/playground-web/package.json | 1 + apps/playground-web/src/app/layout.tsx | 49 ++++++++------- .../src/lib/posthog/Posthog.tsx | 27 +++++++++ .../src/lib/posthog/PosthogHeadSetup.tsx | 10 ++++ .../src/lib/posthog/PosthogPageView.tsx | 33 +++++++++++ apps/portal/src/app/layout.tsx | 59 ++++++++++--------- apps/portal/src/lib/env.ts | 3 + apps/portal/src/lib/posthog/Posthog.tsx | 51 +++++----------- .../src/lib/posthog/PosthogHeadSetup.tsx | 10 ++++ .../src/lib/posthog/PosthogPageView.tsx | 33 +++++++++++ pnpm-lock.yaml | 28 +++++---- 18 files changed, 301 insertions(+), 132 deletions(-) delete mode 100644 apps/dashboard/src/app/components/root-providers.tsx create mode 100644 apps/dashboard/src/lib/posthog/Posthog.tsx create mode 100644 apps/dashboard/src/lib/posthog/PosthogHeadSetup.tsx create mode 100644 apps/dashboard/src/lib/posthog/PosthogPageView.tsx create mode 100644 apps/playground-web/src/lib/posthog/Posthog.tsx create mode 100644 apps/playground-web/src/lib/posthog/PosthogHeadSetup.tsx create mode 100644 apps/playground-web/src/lib/posthog/PosthogPageView.tsx create mode 100644 apps/portal/src/lib/env.ts create mode 100644 apps/portal/src/lib/posthog/PosthogHeadSetup.tsx create mode 100644 apps/portal/src/lib/posthog/PosthogPageView.tsx diff --git a/apps/dashboard/src/app/components/root-providers.tsx b/apps/dashboard/src/app/components/root-providers.tsx deleted file mode 100644 index 2cabadbfbc1..00000000000 --- a/apps/dashboard/src/app/components/root-providers.tsx +++ /dev/null @@ -1,22 +0,0 @@ -// app/providers.tsx -"use client"; -import posthog from "posthog-js"; -import { PostHogProvider as PHProvider } from "posthog-js/react"; - -if (typeof window !== "undefined") { - posthog.init( - process.env.NEXT_PUBLIC_POSTHOG_API_KEY || - "phc_hKK4bo8cHZrKuAVXfXGpfNSLSJuucUnguAgt2j6dgSV", - { - api_host: "https://a.thirdweb.com", - autocapture: true, - debug: false, - capture_pageview: true, - disable_session_recording: true, - }, - ); -} - -export function PostHogProvider({ children }: { children: React.ReactNode }) { - return {children}; -} diff --git a/apps/dashboard/src/app/layout.tsx b/apps/dashboard/src/app/layout.tsx index de2b4c5d931..6a99c541bd2 100644 --- a/apps/dashboard/src/app/layout.tsx +++ b/apps/dashboard/src/app/layout.tsx @@ -8,8 +8,10 @@ import NextTopLoader from "nextjs-toploader"; import { Suspense } from "react"; import { OpCreditsGrantedModalWrapperServer } from "../components/onboarding/OpCreditsGrantedModalWrapperServer"; import { PosthogIdentifierServer } from "../components/wallets/PosthogIdentifierServer"; +import { PHProvider } from "../lib/posthog/Posthog"; +import { PosthogHeadSetup } from "../lib/posthog/PosthogHeadSetup"; +import { PostHogPageView } from "../lib/posthog/PosthogPageView"; import { EnsureValidConnectedWalletLoginServer } from "./components/EnsureValidConnectedWalletLogin/EnsureValidConnectedWalletLoginServer"; -import { PostHogProvider } from "./components/root-providers"; import { AppRouterProviders } from "./providers"; const fontSans = Inter({ @@ -63,8 +65,10 @@ export default function RootLayout({ customDomain="https://pl.thirdweb.com" selfHosted /> + - + + - + ); } diff --git a/apps/dashboard/src/components/wallets/PosthogIdentifier.tsx b/apps/dashboard/src/components/wallets/PosthogIdentifier.tsx index 94c16267da0..0f57a4b2299 100644 --- a/apps/dashboard/src/components/wallets/PosthogIdentifier.tsx +++ b/apps/dashboard/src/components/wallets/PosthogIdentifier.tsx @@ -1,7 +1,7 @@ "use client"; import { useThirdwebClient } from "@/constants/thirdweb.client"; -import posthog from "posthog-js"; +import { usePostHog } from "posthog-js/react"; import { useEffect } from "react"; import { useActiveAccount, @@ -32,48 +32,49 @@ export const PosthogIdentifierClient: React.FC<{ client, }); const wallet = useActiveWallet(); + const posthog = usePostHog(); // legitimate use-case // eslint-disable-next-line no-restricted-syntax useEffect(() => { - if (wallet) { + if (wallet && posthog && posthog.__loaded) { const connector = walletIdToPHName[wallet.id] || wallet.id; posthog.register({ connector }); posthog.capture("wallet_connected", { connector }); } - }, [wallet]); + }, [wallet, posthog]); // legitimate use-case // eslint-disable-next-line no-restricted-syntax useEffect(() => { - if (accountAddress) { + if (accountAddress && posthog && posthog.__loaded) { posthog.identify(accountAddress); } - }, [accountAddress]); + }, [accountAddress, posthog]); // eslint-disable-next-line no-restricted-syntax useEffect(() => { - if (accountId) { + if (accountId && posthog && posthog.__loaded) { posthog.identify(accountId); } - }, [accountId]); + }, [accountId, posthog]); // legitimate use-case // eslint-disable-next-line no-restricted-syntax useEffect(() => { - if (chain?.id) { + if (chain?.id && posthog && posthog.__loaded) { posthog.unregister("network"); posthog.register({ chain_id: chain?.id, ecosystem: "evm" }); } - }, [chain?.id]); + }, [chain?.id, posthog]); // legitimate use-case // eslint-disable-next-line no-restricted-syntax useEffect(() => { - if (balance?.data?.displayValue) { + if (balance?.data?.displayValue && posthog && posthog.__loaded) { posthog.register({ balance: balance.data.displayValue }); } - }, [balance]); + }, [balance, posthog]); return null; }; diff --git a/apps/dashboard/src/lib/posthog/Posthog.tsx b/apps/dashboard/src/lib/posthog/Posthog.tsx new file mode 100644 index 00000000000..48c7fd1f8af --- /dev/null +++ b/apps/dashboard/src/lib/posthog/Posthog.tsx @@ -0,0 +1,28 @@ +"use client"; + +import { isProd } from "@/constants/env"; +import posthog from "posthog-js"; +import { PostHogProvider } from "posthog-js/react"; +import { useEffect } from "react"; + +const NEXT_PUBLIC_POSTHOG_API_KEY = process.env.NEXT_PUBLIC_POSTHOG_API_KEY; + +export function PHProvider({ + children, +}: { + children: React.ReactNode; +}) { + // eslint-disable-next-line no-restricted-syntax + useEffect(() => { + if (NEXT_PUBLIC_POSTHOG_API_KEY && isProd) { + posthog.init(NEXT_PUBLIC_POSTHOG_API_KEY, { + api_host: "https://a.thirdweb.com", + capture_pageview: false, + debug: false, + disable_session_recording: true, + }); + } + }, []); + + return {children}; +} diff --git a/apps/dashboard/src/lib/posthog/PosthogHeadSetup.tsx b/apps/dashboard/src/lib/posthog/PosthogHeadSetup.tsx new file mode 100644 index 00000000000..60b949c0f5b --- /dev/null +++ b/apps/dashboard/src/lib/posthog/PosthogHeadSetup.tsx @@ -0,0 +1,10 @@ +const posthogHost = "https://a.thirdweb.com"; + +export function PosthogHeadSetup() { + return ( + <> + + + + ); +} diff --git a/apps/dashboard/src/lib/posthog/PosthogPageView.tsx b/apps/dashboard/src/lib/posthog/PosthogPageView.tsx new file mode 100644 index 00000000000..d6f3d063b70 --- /dev/null +++ b/apps/dashboard/src/lib/posthog/PosthogPageView.tsx @@ -0,0 +1,34 @@ +"use client"; + +import { usePathname, useSearchParams } from "next/navigation"; +import { usePostHog } from "posthog-js/react"; +import { Suspense, useEffect } from "react"; + +function PostHogPageViewInner() { + const pathname = usePathname(); + const searchParams = useSearchParams(); + const posthog = usePostHog(); + + // eslint-disable-next-line no-restricted-syntax + useEffect(() => { + if (pathname && posthog) { + let url = window.origin + pathname; + if (searchParams.toString()) { + url = `${url}?${searchParams.toString()}`; + } + posthog.capture("$pageview", { + $current_url: url, + }); + } + }, [pathname, searchParams, posthog]); + + return null; +} + +export function PostHogPageView() { + return ( + + + + ); +} diff --git a/apps/playground-web/next.config.mjs b/apps/playground-web/next.config.mjs index da70718cd7b..d0f19b52837 100644 --- a/apps/playground-web/next.config.mjs +++ b/apps/playground-web/next.config.mjs @@ -6,7 +6,7 @@ const ContentSecurityPolicy = ` style-src 'self' 'unsafe-inline'; font-src 'self'; frame-src * data:; - script-src 'self' 'unsafe-eval' 'unsafe-inline' 'wasm-unsafe-eval' 'inline-speculation-rules' *.thirdweb.com *.thirdweb-dev.com vercel.live js.stripe.com; + script-src 'self' 'unsafe-eval' 'unsafe-inline' 'wasm-unsafe-eval' 'inline-speculation-rules' *.thirdweb.com thirdweb.com *.thirdweb-dev.com vercel.live js.stripe.com; connect-src * data: blob:; worker-src 'self' blob:; block-all-mixed-content; diff --git a/apps/playground-web/package.json b/apps/playground-web/package.json index f15e7931e3f..ccfb536215c 100644 --- a/apps/playground-web/package.json +++ b/apps/playground-web/package.json @@ -41,6 +41,7 @@ "next-themes": "^0.4.6", "nextjs-toploader": "^1.6.12", "openapi-types": "^12.1.3", + "posthog-js": "1.67.1", "prettier": "3.5.3", "react": "19.0.0", "react-dom": "19.0.0", diff --git a/apps/playground-web/src/app/layout.tsx b/apps/playground-web/src/app/layout.tsx index dcfbe94c1a1..0908243de5d 100644 --- a/apps/playground-web/src/app/layout.tsx +++ b/apps/playground-web/src/app/layout.tsx @@ -7,6 +7,9 @@ import { AppSidebar } from "./AppSidebar"; import { Providers } from "./providers"; import "./globals.css"; import NextTopLoader from "nextjs-toploader"; +import { PHProvider } from "../lib/posthog/Posthog"; +import { PosthogHeadSetup } from "../lib/posthog/PosthogHeadSetup"; +import { PostHogPageView } from "../lib/posthog/PosthogPageView"; import { MobileHeader } from "./MobileHeader"; import { getSidebarLinks } from "./navLinks"; @@ -43,31 +46,35 @@ export default async function RootLayout({ data-domain="playground.thirdweb.com" data-api="https://pl.thirdweb.com/api/event" /> + - - - -
- -
-
- {children} + + + + + +
+ +
+
+ {children} +
-
- + + ); } diff --git a/apps/playground-web/src/lib/posthog/Posthog.tsx b/apps/playground-web/src/lib/posthog/Posthog.tsx new file mode 100644 index 00000000000..6841f0900ba --- /dev/null +++ b/apps/playground-web/src/lib/posthog/Posthog.tsx @@ -0,0 +1,27 @@ +"use client"; + +import posthog from "posthog-js"; +import { PostHogProvider } from "posthog-js/react"; +import { useEffect } from "react"; +import { isProd } from "../env"; + +const NEXT_PUBLIC_POSTHOG_API_KEY = process.env.NEXT_PUBLIC_POSTHOG_API_KEY; + +export function PHProvider({ + children, +}: { + children: React.ReactNode; +}) { + useEffect(() => { + if (NEXT_PUBLIC_POSTHOG_API_KEY && isProd) { + posthog.init(NEXT_PUBLIC_POSTHOG_API_KEY, { + api_host: "https://a.thirdweb.com", + capture_pageview: false, + debug: false, + disable_session_recording: true, + }); + } + }, []); + + return {children}; +} diff --git a/apps/playground-web/src/lib/posthog/PosthogHeadSetup.tsx b/apps/playground-web/src/lib/posthog/PosthogHeadSetup.tsx new file mode 100644 index 00000000000..60b949c0f5b --- /dev/null +++ b/apps/playground-web/src/lib/posthog/PosthogHeadSetup.tsx @@ -0,0 +1,10 @@ +const posthogHost = "https://a.thirdweb.com"; + +export function PosthogHeadSetup() { + return ( + <> + + + + ); +} diff --git a/apps/playground-web/src/lib/posthog/PosthogPageView.tsx b/apps/playground-web/src/lib/posthog/PosthogPageView.tsx new file mode 100644 index 00000000000..37eee83a388 --- /dev/null +++ b/apps/playground-web/src/lib/posthog/PosthogPageView.tsx @@ -0,0 +1,33 @@ +"use client"; + +import { usePathname, useSearchParams } from "next/navigation"; +import { usePostHog } from "posthog-js/react"; +import { Suspense, useEffect } from "react"; + +function PostHogPageViewInner() { + const pathname = usePathname(); + const searchParams = useSearchParams(); + const posthog = usePostHog(); + + useEffect(() => { + if (pathname && posthog) { + let url = window.origin + pathname; + if (searchParams.toString()) { + url = `${url}?${searchParams.toString()}`; + } + posthog.capture("$pageview", { + $current_url: url, + }); + } + }, [pathname, searchParams, posthog]); + + return null; +} + +export function PostHogPageView() { + return ( + + + + ); +} diff --git a/apps/portal/src/app/layout.tsx b/apps/portal/src/app/layout.tsx index 53923064ae7..5e389dacb45 100644 --- a/apps/portal/src/app/layout.tsx +++ b/apps/portal/src/app/layout.tsx @@ -1,6 +1,6 @@ import "./globals.css"; import { createMetadata } from "@/components/Document"; -import { PosthogHeadSetup, PosthogPageView } from "@/lib/posthog/Posthog"; +import { PosthogHeadSetup } from "@/lib/posthog/PosthogHeadSetup"; import { Fira_Code, Inter } from "next/font/google"; import Script from "next/script"; import NextTopLoader from "nextjs-toploader"; @@ -8,6 +8,8 @@ import { StickyTopContainer } from "../components/Document/StickyTopContainer"; import { Banner } from "../components/others/Banner"; import { EnableSmoothScroll } from "../components/others/SmoothScroll"; import { SetStoredTheme } from "../components/others/theme/theme"; +import { PHProvider } from "../lib/posthog/Posthog"; +import { PostHogPageView } from "../lib/posthog/PosthogPageView"; import { cn } from "../lib/utils"; import { Header } from "./Header"; @@ -44,33 +46,36 @@ export default function RootLayout({ data-api="https://pl.thirdweb.com/api/event" /> - - - - - + + + + + + + +
+ + {/* Note: Please change id as well when changing text or href so that new banner is shown to user even if user dismissed the older one */} + +
+ -
- - {/* Note: Please change id as well when changing text or href so that new banner is shown to user even if user dismissed the older one */} - -
- - {children} -
- + {children} +
+ +
); } diff --git a/apps/portal/src/lib/env.ts b/apps/portal/src/lib/env.ts new file mode 100644 index 00000000000..09f66ab1786 --- /dev/null +++ b/apps/portal/src/lib/env.ts @@ -0,0 +1,3 @@ +export const isProd = + (process.env.VERCEL_ENV || process.env.NEXT_PUBLIC_VERCEL_ENV) === + "production"; diff --git a/apps/portal/src/lib/posthog/Posthog.tsx b/apps/portal/src/lib/posthog/Posthog.tsx index 66236950ba7..6841f0900ba 100644 --- a/apps/portal/src/lib/posthog/Posthog.tsx +++ b/apps/portal/src/lib/posthog/Posthog.tsx @@ -1,46 +1,27 @@ "use client"; -import { usePathname } from "next/navigation"; import posthog from "posthog-js"; +import { PostHogProvider } from "posthog-js/react"; import { useEffect } from "react"; +import { isProd } from "../env"; -const posthogHost = "https://a.thirdweb.com"; -const apiKey = "phc_hKK4bo8cHZrKuAVXfXGpfNSLSJuucUnguAgt2j6dgSV"; - -// Check that PostHog is client-side (used to handle Next.js SSR) -if (typeof window !== "undefined" && process.env.NODE_ENV !== "development") { - posthog.init(apiKey, { - api_host: posthogHost, - // Enable debug mode in development - // loaded: (posthog) => { - // if (process.env.NODE_ENV === "development") { - // posthog.debug(); - // } - // }, - }); -} - -// Track pageviews -export function PosthogPageView() { - const pathname = usePathname(); +const NEXT_PUBLIC_POSTHOG_API_KEY = process.env.NEXT_PUBLIC_POSTHOG_API_KEY; +export function PHProvider({ + children, +}: { + children: React.ReactNode; +}) { useEffect(() => { - if (pathname) { - posthog.capture("$pageview", { - $current_url: window.origin + pathname, + if (NEXT_PUBLIC_POSTHOG_API_KEY && isProd) { + posthog.init(NEXT_PUBLIC_POSTHOG_API_KEY, { + api_host: "https://a.thirdweb.com", + capture_pageview: false, + debug: false, + disable_session_recording: true, }); } - }, [pathname]); - - return null; -} + }, []); -// Render this in the of the page -export function PosthogHeadSetup() { - return ( - <> - - - - ); + return {children}; } diff --git a/apps/portal/src/lib/posthog/PosthogHeadSetup.tsx b/apps/portal/src/lib/posthog/PosthogHeadSetup.tsx new file mode 100644 index 00000000000..60b949c0f5b --- /dev/null +++ b/apps/portal/src/lib/posthog/PosthogHeadSetup.tsx @@ -0,0 +1,10 @@ +const posthogHost = "https://a.thirdweb.com"; + +export function PosthogHeadSetup() { + return ( + <> + + + + ); +} diff --git a/apps/portal/src/lib/posthog/PosthogPageView.tsx b/apps/portal/src/lib/posthog/PosthogPageView.tsx new file mode 100644 index 00000000000..37eee83a388 --- /dev/null +++ b/apps/portal/src/lib/posthog/PosthogPageView.tsx @@ -0,0 +1,33 @@ +"use client"; + +import { usePathname, useSearchParams } from "next/navigation"; +import { usePostHog } from "posthog-js/react"; +import { Suspense, useEffect } from "react"; + +function PostHogPageViewInner() { + const pathname = usePathname(); + const searchParams = useSearchParams(); + const posthog = usePostHog(); + + useEffect(() => { + if (pathname && posthog) { + let url = window.origin + pathname; + if (searchParams.toString()) { + url = `${url}?${searchParams.toString()}`; + } + posthog.capture("$pageview", { + $current_url: url, + }); + } + }, [pathname, searchParams, posthog]); + + return null; +} + +export function PostHogPageView() { + return ( + + + + ); +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5b9143cbc27..b156293e867 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -591,6 +591,9 @@ importers: openapi-types: specifier: ^12.1.3 version: 12.1.3 + posthog-js: + specifier: 1.67.1 + version: 1.67.1 prettier: specifier: 3.5.3 version: 3.5.3 @@ -10740,6 +10743,7 @@ packages: lodash.isequal@4.5.0: resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -26294,8 +26298,8 @@ snapshots: '@typescript-eslint/parser': 7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2) eslint: 9.22.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.8.3(eslint-plugin-import@2.31.0)(eslint@9.22.0(jiti@2.4.2)) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.3)(eslint@9.22.0(jiti@2.4.2)) + eslint-import-resolver-typescript: 3.8.3(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.22.0(jiti@2.4.2)) eslint-plugin-react: 7.37.4(eslint@9.22.0(jiti@2.4.2)) eslint-plugin-react-hooks: 5.1.0(eslint@9.22.0(jiti@2.4.2)) @@ -26314,33 +26318,33 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0)(eslint@8.57.0): + eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.0(supports-color@8.1.1) enhanced-resolve: 5.18.1 - eslint: 8.57.0 + eslint: 9.22.0(jiti@2.4.2) get-tsconfig: 4.10.0 is-bun-module: 1.3.0 stable-hash: 0.0.4 tinyglobby: 0.2.12 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.3)(eslint@8.57.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0)(eslint@9.22.0(jiti@2.4.2)): + eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0)(eslint@8.57.0): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.0(supports-color@8.1.1) enhanced-resolve: 5.18.1 - eslint: 9.22.0(jiti@2.4.2) + eslint: 8.57.0 get-tsconfig: 4.10.0 is-bun-module: 1.3.0 stable-hash: 0.0.4 tinyglobby: 0.2.12 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.3)(eslint@9.22.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.3)(eslint@8.57.0) transitivePeerDependencies: - supports-color @@ -26376,14 +26380,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0)(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2) eslint: 9.22.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.8.3(eslint-plugin-import@2.31.0)(eslint@9.22.0(jiti@2.4.2)) + eslint-import-resolver-typescript: 3.8.3(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color @@ -26416,7 +26420,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.3)(eslint@9.22.0(jiti@2.4.2)): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -26427,7 +26431,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.22.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0)(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.14.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3