diff --git a/packages/app-insights/package.json b/packages/app-insights/package.json new file mode 100644 index 000000000..be6d44755 --- /dev/null +++ b/packages/app-insights/package.json @@ -0,0 +1,73 @@ +{ + "name": "@logto/app-insights", + "version": "1.0.0", + "main": "lib/index.js", + "author": "Silverhand Inc. ", + "license": "MPL-2.0", + "type": "module", + "files": [ + "lib" + ], + "exports": { + ".": { + "import": "./lib/index.js" + }, + "./*": { + "import": "./lib/*" + } + }, + "publishConfig": { + "access": "public" + }, + "scripts": { + "precommit": "lint-staged", + "build": "rm -rf lib/ && tsc -p tsconfig.build.json", + "build:test": "pnpm build", + "dev": "tsc -p tsconfig.build.json --watch --preserveWatchOutput --incremental", + "lint": "eslint --ext .ts src", + "lint:report": "pnpm lint --format json --output-file report.json", + "prepack": "pnpm build" + }, + "devDependencies": { + "@silverhand/eslint-config": "3.0.0", + "@silverhand/ts-config": "3.0.0", + "@types/node": "^18.11.18", + "@types/react": "^18.0.31", + "eslint": "^8.34.0", + "history": "^5.3.0", + "lint-staged": "^13.0.0", + "prettier": "^2.8.2", + "react": "^18.0.0", + "tslib": "^2.4.1", + "typescript": "^5.0.0" + }, + "engines": { + "node": "^18.12.0" + }, + "eslintConfig": { + "extends": "@silverhand" + }, + "prettier": "@silverhand/eslint-config/.prettierrc", + "dependencies": { + "@microsoft/applicationinsights-react-js": "^3.4.1", + "@microsoft/applicationinsights-web": "^2.8.11", + "@silverhand/essentials": "^2.5.0", + "applicationinsights": "^2.5.0" + }, + "peerDependencies": { + "history": "^5.3.0", + "react": "^18.0.0", + "tslib": "^2.4.1" + }, + "peerDependenciesMeta": { + "history": { + "optional": true + }, + "react": { + "optional": true + }, + "tslib": { + "optional": true + } + } +} diff --git a/packages/shared/src/app-insights/index.ts b/packages/app-insights/src/node.ts similarity index 100% rename from packages/shared/src/app-insights/index.ts rename to packages/app-insights/src/node.ts diff --git a/packages/app-insights/src/react.ts b/packages/app-insights/src/react.ts new file mode 100644 index 000000000..7988f1672 --- /dev/null +++ b/packages/app-insights/src/react.ts @@ -0,0 +1,64 @@ +import { ReactPlugin, withAITracking } from '@microsoft/applicationinsights-react-js'; +import { ApplicationInsights } from '@microsoft/applicationinsights-web'; +import { type Optional } from '@silverhand/essentials'; +import { type ComponentType } from 'react'; + +class AppInsightsReact { + protected reactPlugin?: ReactPlugin; + protected appInsights?: ApplicationInsights; + + get instance(): Optional { + return this.appInsights; + } + + get trackPageView(): Optional { + return this.appInsights?.trackPageView.bind(this.appInsights); + } + + setup(): boolean { + // The string needs to be normalized since it may contain '"' + const connectionString = process.env.APPLICATIONINSIGHTS_CONNECTION_STRING?.replace( + /^"?(.*)"?$/g, + '$1' + ); + + if (!connectionString) { + return false; + } + + if (this.appInsights?.config.connectionString === connectionString) { + return true; + } + + try { + // https://github.com/microsoft/applicationinsights-react-js#readme + this.reactPlugin = new ReactPlugin(); + this.appInsights = new ApplicationInsights({ + config: { + connectionString, + enableAutoRouteTracking: false, + extensions: [this.reactPlugin], + }, + }); + + this.appInsights.loadAppInsights(); + } catch (error: unknown) { + console.error('Unable to init ApplicationInsights:'); + console.error(error); + + return false; + } + + return true; + } + + withAppInsights

(Component: ComponentType

): ComponentType

{ + if (!this.reactPlugin) { + return Component; + } + + return withAITracking(this.reactPlugin, Component, undefined, 'appInsightsWrapper'); + } +} + +export const appInsightsReact = new AppInsightsReact(); diff --git a/packages/app-insights/tsconfig.build.json b/packages/app-insights/tsconfig.build.json new file mode 100644 index 000000000..695fba3f1 --- /dev/null +++ b/packages/app-insights/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig", + "include": ["src"] +} diff --git a/packages/app-insights/tsconfig.json b/packages/app-insights/tsconfig.json new file mode 100644 index 000000000..225658205 --- /dev/null +++ b/packages/app-insights/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "@silverhand/ts-config/tsconfig.base", + "compilerOptions": { + "outDir": "lib", + "types": ["node"] + }, + "include": [ + "src" + ] +} diff --git a/packages/cloud/package.json b/packages/cloud/package.json index 5069b1a76..2fdd99d4e 100644 --- a/packages/cloud/package.json +++ b/packages/cloud/package.json @@ -23,6 +23,7 @@ "test:ci": "pnpm test:only --coverage --silent" }, "dependencies": { + "@logto/app-insights": "workspace:^", "@logto/cli": "workspace:^", "@logto/connector-kit": "workspace:^", "@logto/core-kit": "workspace:^", @@ -32,7 +33,6 @@ "@withtyped/postgres": "^0.8.1", "@withtyped/server": "^0.8.1", "accepts": "^1.3.8", - "applicationinsights": "^2.5.0", "chalk": "^5.0.0", "decamelize": "^6.0.0", "dotenv": "^16.0.0", diff --git a/packages/cloud/src/index.ts b/packages/cloud/src/index.ts index 6b0c6fcdc..e941fb588 100644 --- a/packages/cloud/src/index.ts +++ b/packages/cloud/src/index.ts @@ -6,8 +6,11 @@ import { findUp } from 'find-up'; dotenv.config({ path: await findUp('.env', {}) }); -const { appInsights } = await import('@logto/shared/app-insights'); -appInsights.setup('logto-cloud'); +const { appInsights } = await import('@logto/app-insights/node.js'); + +if (appInsights.setup('logto-cloud')) { + console.debug('Initialized ApplicationInsights'); +} const { default: withAuth } = await import('./middleware/with-auth.js'); const { default: withHttpProxy } = await import('./middleware/with-http-proxy.js'); diff --git a/packages/cloud/src/middleware/with-error-report.ts b/packages/cloud/src/middleware/with-error-report.ts index 4001b4789..86b387ce0 100644 --- a/packages/cloud/src/middleware/with-error-report.ts +++ b/packages/cloud/src/middleware/with-error-report.ts @@ -1,4 +1,4 @@ -import { appInsights } from '@logto/shared/app-insights'; +import { appInsights } from '@logto/app-insights/node.js'; import { tryThat } from '@silverhand/essentials'; import type { BaseContext, NextFunction } from '@withtyped/server'; diff --git a/packages/console/package.json b/packages/console/package.json index f7fccc6d8..fb2fc9d48 100644 --- a/packages/console/package.json +++ b/packages/console/package.json @@ -19,6 +19,7 @@ }, "devDependencies": { "@fontsource/roboto-mono": "^4.5.7", + "@logto/app-insights": "workspace:^", "@logto/connector-kit": "workspace:^", "@logto/core-kit": "workspace:^", "@logto/language-kit": "workspace:^", @@ -27,8 +28,6 @@ "@logto/react": "1.1.0", "@logto/schemas": "workspace:^", "@mdx-js/react": "^1.6.22", - "@microsoft/applicationinsights-react-js": "^3.4.1", - "@microsoft/applicationinsights-web": "^2.8.11", "@parcel/compressor-brotli": "2.8.3", "@parcel/compressor-gzip": "2.8.3", "@parcel/core": "2.8.3", @@ -44,7 +43,7 @@ "@types/color": "^3.0.3", "@types/mdx": "^2.0.1", "@types/mdx-js__react": "^1.5.5", - "@types/react": "^18.0.0", + "@types/react": "^18.0.31", "@types/react-dom": "^18.0.0", "@types/react-helmet": "^6.1.6", "@types/react-modal": "^3.13.1", diff --git a/packages/console/src/App.tsx b/packages/console/src/App.tsx index 2e43933f8..ac7c7fad2 100644 --- a/packages/console/src/App.tsx +++ b/packages/console/src/App.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import { UserScope } from '@logto/core-kit'; import { LogtoProvider } from '@logto/react'; import { adminConsoleApplicationId, PredefinedScope } from '@logto/schemas'; @@ -25,6 +26,9 @@ import AppEndpointsProvider from './contexts/AppEndpointsProvider'; import { AppThemeProvider } from './contexts/AppThemeProvider'; import TenantsProvider, { TenantsContext } from './contexts/TenantsProvider'; +if (appInsightsReact.setup()) { + console.debug('Initialized ApplicationInsights'); +} void initI18n(); function Content() { diff --git a/packages/console/src/components/PageMeta/index.tsx b/packages/console/src/components/PageMeta/index.tsx index d06088210..dc3299145 100644 --- a/packages/console/src/components/PageMeta/index.tsx +++ b/packages/console/src/components/PageMeta/index.tsx @@ -1,9 +1,10 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import type { AdminConsoleKey } from '@logto/phrases'; import { useEffect, useState } from 'react'; import { Helmet } from 'react-helmet'; import { useTranslation } from 'react-i18next'; -import { getAppInsights } from '@/utils/app-insights'; +import { mainTitle } from '@/consts/tenants'; type Props = { titleKey: AdminConsoleKey | AdminConsoleKey[]; @@ -21,7 +22,7 @@ function PageMeta({ titleKey, trackPageView = true }: Props) { useEffect(() => { // Only track once for the same page if (trackPageView && !pageViewTracked) { - getAppInsights()?.trackPageView({ name: rawTitle }); + appInsightsReact.trackPageView?.({ name: [rawTitle, mainTitle].join(' - ') }); setPageViewTracked(true); } }, [pageViewTracked, rawTitle, trackPageView]); diff --git a/packages/console/src/hooks/use-track-user-id.ts b/packages/console/src/hooks/use-track-user-id.ts index a3a9de2da..ba8e8c6ad 100644 --- a/packages/console/src/hooks/use-track-user-id.ts +++ b/packages/console/src/hooks/use-track-user-id.ts @@ -1,9 +1,8 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import { useLogto } from '@logto/react'; import { trySafe } from '@silverhand/essentials'; import { useEffect } from 'react'; -import { getAppInsights } from '@/utils/app-insights'; - class NoIdTokenClaimsError extends Error { name = 'NoIdTokenClaimsError'; message = 'Cloud not fetch ID Token claims where user is authenticated.'; @@ -14,7 +13,7 @@ const useTrackUserId = () => { useEffect(() => { const setUserId = async () => { - const appInsights = getAppInsights(); + const { instance: appInsights } = appInsightsReact; if (!appInsights) { return; diff --git a/packages/console/src/onboarding/pages/About/index.tsx b/packages/console/src/onboarding/pages/About/index.tsx index c97fae3cf..39168fe02 100644 --- a/packages/console/src/onboarding/pages/About/index.tsx +++ b/packages/console/src/onboarding/pages/About/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import { conditional } from '@silverhand/essentials'; import { useEffect } from 'react'; import { Controller, useForm } from 'react-hook-form'; @@ -12,7 +13,6 @@ import PageMeta from '@/components/PageMeta'; import TextInput from '@/components/TextInput'; import useUserOnboardingData from '@/onboarding/hooks/use-user-onboarding-data'; import * as pageLayout from '@/onboarding/scss/layout.module.scss'; -import { withAppInsights } from '@/utils/app-insights'; import ActionBar from '../../components/ActionBar'; import { CardSelector, MultiCardSelector } from '../../components/CardSelector'; @@ -144,4 +144,4 @@ function About() { ); } -export default withAppInsights(About); +export default appInsightsReact.withAppInsights(About); diff --git a/packages/console/src/onboarding/pages/Congrats/index.tsx b/packages/console/src/onboarding/pages/Congrats/index.tsx index d7d2bc3f3..b6b5f6820 100644 --- a/packages/console/src/onboarding/pages/Congrats/index.tsx +++ b/packages/console/src/onboarding/pages/Congrats/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import classNames from 'classnames'; import { useContext } from 'react'; import { Trans, useTranslation } from 'react-i18next'; @@ -12,7 +13,6 @@ import { TenantsContext } from '@/contexts/TenantsProvider'; import Reservation from '@/onboarding/components/Reservation'; import useUserOnboardingData from '@/onboarding/hooks/use-user-onboarding-data'; import * as pageLayout from '@/onboarding/scss/layout.module.scss'; -import { withAppInsights } from '@/utils/app-insights'; import * as styles from './index.module.scss'; @@ -59,4 +59,4 @@ function Congrats() { ); } -export default withAppInsights(Congrats); +export default appInsightsReact.withAppInsights(Congrats); diff --git a/packages/console/src/onboarding/pages/SignInExperience/index.tsx b/packages/console/src/onboarding/pages/SignInExperience/index.tsx index 8997b56df..a8b92fdbb 100644 --- a/packages/console/src/onboarding/pages/SignInExperience/index.tsx +++ b/packages/console/src/onboarding/pages/SignInExperience/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import type { SignInExperience as SignInExperienceType } from '@logto/schemas'; import { SignInIdentifier } from '@logto/schemas'; import { useCallback, useEffect, useMemo } from 'react'; @@ -24,7 +25,6 @@ import * as pageLayout from '@/onboarding/scss/layout.module.scss'; import type { OnboardingSieConfig } from '@/onboarding/types'; import { Authentication, OnboardingPage } from '@/onboarding/types'; import { getOnboardingPage } from '@/onboarding/utils'; -import { withAppInsights } from '@/utils/app-insights'; import { buildUrl } from '@/utils/url'; import { uriValidator } from '@/utils/validator'; @@ -256,4 +256,4 @@ function SignInExperience() { ); } -export default withAppInsights(SignInExperience); +export default appInsightsReact.withAppInsights(SignInExperience); diff --git a/packages/console/src/onboarding/pages/Welcome/index.tsx b/packages/console/src/onboarding/pages/Welcome/index.tsx index ef4c71d58..d2d3b211e 100644 --- a/packages/console/src/onboarding/pages/Welcome/index.tsx +++ b/packages/console/src/onboarding/pages/Welcome/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import classNames from 'classnames'; import { useEffect } from 'react'; import { Controller, useForm } from 'react-hook-form'; @@ -13,7 +14,6 @@ import ActionBar from '@/onboarding/components/ActionBar'; import { CardSelector } from '@/onboarding/components/CardSelector'; import useUserOnboardingData from '@/onboarding/hooks/use-user-onboarding-data'; import * as pageLayout from '@/onboarding/scss/layout.module.scss'; -import { withAppInsights } from '@/utils/app-insights'; import type { Questionnaire } from '../../types'; import { OnboardingPage } from '../../types'; @@ -111,4 +111,4 @@ function Welcome() { ); } -export default withAppInsights(Welcome); +export default appInsightsReact.withAppInsights(Welcome); diff --git a/packages/console/src/pages/ApiResourceDetails/index.tsx b/packages/console/src/pages/ApiResourceDetails/index.tsx index 587c6ed97..9f378bc00 100644 --- a/packages/console/src/pages/ApiResourceDetails/index.tsx +++ b/packages/console/src/pages/ApiResourceDetails/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import type { Resource } from '@logto/schemas'; import { isManagementApi, Theme } from '@logto/schemas'; import classNames from 'classnames'; @@ -22,7 +23,6 @@ import { ApiResourceDetailsTabs } from '@/consts/page-tabs'; import type { RequestError } from '@/hooks/use-api'; import useApi from '@/hooks/use-api'; import useTheme from '@/hooks/use-theme'; -import { withAppInsights } from '@/utils/app-insights'; import * as styles from './index.module.scss'; import { type ApiResourceDetailsOutletContext } from './types'; @@ -148,4 +148,4 @@ function ApiResourceDetails() { ); } -export default withAppInsights(ApiResourceDetails); +export default appInsightsReact.withAppInsights(ApiResourceDetails); diff --git a/packages/console/src/pages/ApiResources/index.tsx b/packages/console/src/pages/ApiResources/index.tsx index 57150804c..dc1d83590 100644 --- a/packages/console/src/pages/ApiResources/index.tsx +++ b/packages/console/src/pages/ApiResources/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import type { Resource } from '@logto/schemas'; import { Theme } from '@logto/schemas'; import { toast } from 'react-hot-toast'; @@ -24,7 +25,6 @@ import useSearchParametersWatcher from '@/hooks/use-search-parameters-watcher'; import useTheme from '@/hooks/use-theme'; import * as modalStyles from '@/scss/modal.module.scss'; import * as resourcesStyles from '@/scss/resources.module.scss'; -import { withAppInsights } from '@/utils/app-insights'; import { buildUrl } from '@/utils/url'; import CreateForm from './components/CreateForm'; @@ -151,4 +151,4 @@ function ApiResources() { ); } -export default withAppInsights(ApiResources); +export default appInsightsReact.withAppInsights(ApiResources); diff --git a/packages/console/src/pages/ApplicationDetails/index.tsx b/packages/console/src/pages/ApplicationDetails/index.tsx index 5e806ad6d..f7cdaadee 100644 --- a/packages/console/src/pages/ApplicationDetails/index.tsx +++ b/packages/console/src/pages/ApplicationDetails/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import type { Application, ApplicationResponse, SnakeCaseOidcConfig } from '@logto/schemas'; import { ApplicationType } from '@logto/schemas'; import { useEffect, useState } from 'react'; @@ -25,7 +26,6 @@ import type { RequestError } from '@/hooks/use-api'; import useApi from '@/hooks/use-api'; import useDocumentationUrl from '@/hooks/use-documentation-url'; import { applicationTypeI18nKey } from '@/types/applications'; -import { withAppInsights } from '@/utils/app-insights'; import Guide from '../Applications/components/Guide'; import GuideModal from '../Applications/components/Guide/GuideModal'; @@ -235,4 +235,4 @@ function ApplicationDetails() { ); } -export default withAppInsights(ApplicationDetails); +export default appInsightsReact.withAppInsights(ApplicationDetails); diff --git a/packages/console/src/pages/Applications/index.tsx b/packages/console/src/pages/Applications/index.tsx index f9ad1b59c..de396451d 100644 --- a/packages/console/src/pages/Applications/index.tsx +++ b/packages/console/src/pages/Applications/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import type { Application } from '@logto/schemas'; import { ApplicationType } from '@logto/schemas'; import { useTranslation } from 'react-i18next'; @@ -18,7 +19,6 @@ import type { RequestError } from '@/hooks/use-api'; import useSearchParametersWatcher from '@/hooks/use-search-parameters-watcher'; import * as resourcesStyles from '@/scss/resources.module.scss'; import { applicationTypeI18nKey } from '@/types/applications'; -import { withAppInsights } from '@/utils/app-insights'; import { buildUrl } from '@/utils/url'; import ApplicationsPlaceholder from './components/ApplicationsPlaceholder'; @@ -147,4 +147,4 @@ function Applications() { ); } -export default withAppInsights(Applications); +export default appInsightsReact.withAppInsights(Applications); diff --git a/packages/console/src/pages/AuditLogDetails/index.tsx b/packages/console/src/pages/AuditLogDetails/index.tsx index 66813d65b..09a95c7b2 100644 --- a/packages/console/src/pages/AuditLogDetails/index.tsx +++ b/packages/console/src/pages/AuditLogDetails/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import type { User, Log } from '@logto/schemas'; import { demoAppApplicationId } from '@logto/schemas'; import { useTranslation } from 'react-i18next'; @@ -15,7 +16,6 @@ import TabNav, { TabNavItem } from '@/components/TabNav'; import UserName from '@/components/UserName'; import { logEventTitle } from '@/consts/logs'; import type { RequestError } from '@/hooks/use-api'; -import { withAppInsights } from '@/utils/app-insights'; import EventIcon from './components/EventIcon'; import * as styles from './index.module.scss'; @@ -122,4 +122,4 @@ function AuditLogDetails() { ); } -export default withAppInsights(AuditLogDetails); +export default appInsightsReact.withAppInsights(AuditLogDetails); diff --git a/packages/console/src/pages/AuditLogs/index.tsx b/packages/console/src/pages/AuditLogs/index.tsx index 2539692a0..f7110adca 100644 --- a/packages/console/src/pages/AuditLogs/index.tsx +++ b/packages/console/src/pages/AuditLogs/index.tsx @@ -1,8 +1,9 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; + import AuditLogTable from '@/components/AuditLogTable'; import CardTitle from '@/components/CardTitle'; import PageMeta from '@/components/PageMeta'; import * as resourcesStyles from '@/scss/resources.module.scss'; -import { withAppInsights } from '@/utils/app-insights'; function AuditLogs() { return ( @@ -16,4 +17,4 @@ function AuditLogs() { ); } -export default withAppInsights(AuditLogs); +export default appInsightsReact.withAppInsights(AuditLogs); diff --git a/packages/console/src/pages/ConnectorDetails/index.tsx b/packages/console/src/pages/ConnectorDetails/index.tsx index 399e2d8c2..97ef843e0 100644 --- a/packages/console/src/pages/ConnectorDetails/index.tsx +++ b/packages/console/src/pages/ConnectorDetails/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import { ConnectorType } from '@logto/schemas'; import type { ConnectorFactoryResponse, ConnectorResponse } from '@logto/schemas'; import { useEffect, useState } from 'react'; @@ -25,7 +26,6 @@ import { ConnectorsTabs } from '@/consts/page-tabs'; import type { RequestError } from '@/hooks/use-api'; import useApi from '@/hooks/use-api'; import useConnectorInUse from '@/hooks/use-connector-in-use'; -import { withAppInsights } from '@/utils/app-insights'; import CreateForm from '../Connectors/components/CreateForm'; @@ -235,4 +235,4 @@ function ConnectorDetails() { ); } -export default withAppInsights(ConnectorDetails); +export default appInsightsReact.withAppInsights(ConnectorDetails); diff --git a/packages/console/src/pages/Connectors/index.tsx b/packages/console/src/pages/Connectors/index.tsx index d13bd4a72..61639b10f 100644 --- a/packages/console/src/pages/Connectors/index.tsx +++ b/packages/console/src/pages/Connectors/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import type { ConnectorFactoryResponse } from '@logto/schemas'; import { ConnectorType } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; @@ -23,7 +24,6 @@ import useConnectorGroups from '@/hooks/use-connector-groups'; import useDocumentationUrl from '@/hooks/use-documentation-url'; import DemoConnectorNotice from '@/onboarding/components/DemoConnectorNotice'; import * as resourcesStyles from '@/scss/resources.module.scss'; -import { withAppInsights } from '@/utils/app-insights'; import ConnectorDeleteButton from './components/ConnectorDeleteButton'; import ConnectorName from './components/ConnectorName'; @@ -225,4 +225,4 @@ function Connectors() { ); } -export default withAppInsights(Connectors); +export default appInsightsReact.withAppInsights(Connectors); diff --git a/packages/console/src/pages/Dashboard/index.tsx b/packages/console/src/pages/Dashboard/index.tsx index f046ba2f0..6a12ddf5f 100644 --- a/packages/console/src/pages/Dashboard/index.tsx +++ b/packages/console/src/pages/Dashboard/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import { format } from 'date-fns'; import type { ChangeEventHandler } from 'react'; import { useState } from 'react'; @@ -18,7 +19,6 @@ import Card from '@/components/Card'; import PageMeta from '@/components/PageMeta'; import TextInput from '@/components/TextInput'; import type { RequestError } from '@/hooks/use-api'; -import { withAppInsights } from '@/utils/app-insights'; import Block from './components/Block'; import ChartTooltip from './components/ChartTooltip'; @@ -153,4 +153,4 @@ function Dashboard() { ); } -export default withAppInsights(Dashboard); +export default appInsightsReact.withAppInsights(Dashboard); diff --git a/packages/console/src/pages/GetStarted/index.tsx b/packages/console/src/pages/GetStarted/index.tsx index 6467b8ea3..9ce6219cb 100644 --- a/packages/console/src/pages/GetStarted/index.tsx +++ b/packages/console/src/pages/GetStarted/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; @@ -9,7 +10,6 @@ import ConfirmModal from '@/components/ConfirmModal'; import PageMeta from '@/components/PageMeta'; import Spacer from '@/components/Spacer'; import useUserPreferences from '@/hooks/use-user-preferences'; -import { withAppInsights } from '@/utils/app-insights'; import Skeleton from './components/Skeleton'; import useGetStartedMetadata from './hook'; @@ -99,4 +99,4 @@ function GetStarted() { ); } -export default withAppInsights(GetStarted); +export default appInsightsReact.withAppInsights(GetStarted); diff --git a/packages/console/src/pages/Profile/index.tsx b/packages/console/src/pages/Profile/index.tsx index 182b4305b..dcea7e17e 100644 --- a/packages/console/src/pages/Profile/index.tsx +++ b/packages/console/src/pages/Profile/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import type { ConnectorResponse } from '@logto/schemas'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; @@ -16,7 +17,6 @@ import useCurrentUser from '@/hooks/use-current-user'; import useSwrFetcher from '@/hooks/use-swr-fetcher'; import useUserAssetsService from '@/hooks/use-user-assets-service'; import * as resourcesStyles from '@/scss/resources.module.scss'; -import { withAppInsights } from '@/utils/app-insights'; import BasicUserInfoSection from './components/BasicUserInfoSection'; import CardContent from './components/CardContent'; @@ -99,4 +99,4 @@ function Profile() { ); } -export default withAppInsights(Profile); +export default appInsightsReact.withAppInsights(Profile); diff --git a/packages/console/src/pages/RoleDetails/index.tsx b/packages/console/src/pages/RoleDetails/index.tsx index da0b994f9..413e24c59 100644 --- a/packages/console/src/pages/RoleDetails/index.tsx +++ b/packages/console/src/pages/RoleDetails/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import type { Role } from '@logto/schemas'; import classNames from 'classnames'; import { useEffect, useState } from 'react'; @@ -17,7 +18,6 @@ import TabNav, { TabNavItem } from '@/components/TabNav'; import { RoleDetailsTabs } from '@/consts/page-tabs'; import type { RequestError } from '@/hooks/use-api'; import useApi from '@/hooks/use-api'; -import { withAppInsights } from '@/utils/app-insights'; import * as styles from './index.module.scss'; import { type RoleDetailsOutletContext } from './types'; @@ -135,4 +135,4 @@ function RoleDetails() { ); } -export default withAppInsights(RoleDetails); +export default appInsightsReact.withAppInsights(RoleDetails); diff --git a/packages/console/src/pages/Roles/index.tsx b/packages/console/src/pages/Roles/index.tsx index 980c84d5f..e1ab117b9 100644 --- a/packages/console/src/pages/Roles/index.tsx +++ b/packages/console/src/pages/Roles/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import type { RoleResponse } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; import { useTranslation } from 'react-i18next'; @@ -19,7 +20,6 @@ import type { RequestError } from '@/hooks/use-api'; import useDocumentationUrl from '@/hooks/use-documentation-url'; import useSearchParametersWatcher from '@/hooks/use-search-parameters-watcher'; import * as pageStyles from '@/scss/resources.module.scss'; -import { withAppInsights } from '@/utils/app-insights'; import { buildUrl, formatSearchKeyword } from '@/utils/url'; import AssignedUsers from './components/AssignedUsers'; @@ -163,4 +163,4 @@ function Roles() { ); } -export default withAppInsights(Roles); +export default appInsightsReact.withAppInsights(Roles); diff --git a/packages/console/src/pages/SignInExperience/index.tsx b/packages/console/src/pages/SignInExperience/index.tsx index 6413be43d..81a724058 100644 --- a/packages/console/src/pages/SignInExperience/index.tsx +++ b/packages/console/src/pages/SignInExperience/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import type { SignInExperience as SignInExperienceType } from '@logto/schemas'; import classNames from 'classnames'; import type { ReactNode } from 'react'; @@ -22,7 +23,6 @@ import useApi from '@/hooks/use-api'; import useConfigs from '@/hooks/use-configs'; import useUiLanguages from '@/hooks/use-ui-languages'; import useUserAssetsService from '@/hooks/use-user-assets-service'; -import { withAppInsights } from '@/utils/app-insights'; import Preview from './components/Preview'; import SignUpAndSignInChangePreview from './components/SignUpAndSignInChangePreview'; @@ -252,4 +252,4 @@ function SignInExperience() { ); } -export default withAppInsights(SignInExperience); +export default appInsightsReact.withAppInsights(SignInExperience); diff --git a/packages/console/src/pages/UserDetails/index.tsx b/packages/console/src/pages/UserDetails/index.tsx index 75eebb206..3a19bf828 100644 --- a/packages/console/src/pages/UserDetails/index.tsx +++ b/packages/console/src/pages/UserDetails/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import type { User } from '@logto/schemas'; import classNames from 'classnames'; import { useEffect, useState } from 'react'; @@ -22,7 +23,6 @@ import { UserDetailsTabs } from '@/consts/page-tabs'; import type { RequestError } from '@/hooks/use-api'; import useApi from '@/hooks/use-api'; import * as modalStyles from '@/scss/modal.module.scss'; -import { withAppInsights } from '@/utils/app-insights'; import UserAccountInformation from '../../components/UserAccountInformation'; @@ -192,4 +192,4 @@ function UserDetails() { ); } -export default withAppInsights(UserDetails); +export default appInsightsReact.withAppInsights(UserDetails); diff --git a/packages/console/src/pages/Users/index.tsx b/packages/console/src/pages/Users/index.tsx index 16c1cb981..472d88867 100644 --- a/packages/console/src/pages/Users/index.tsx +++ b/packages/console/src/pages/Users/index.tsx @@ -1,3 +1,4 @@ +import { appInsightsReact } from '@logto/app-insights/lib/react'; import type { User } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; import { useTranslation } from 'react-i18next'; @@ -22,7 +23,6 @@ import { UserDetailsTabs } from '@/consts/page-tabs'; import type { RequestError } from '@/hooks/use-api'; import useSearchParametersWatcher from '@/hooks/use-search-parameters-watcher'; import * as resourcesStyles from '@/scss/resources.module.scss'; -import { withAppInsights } from '@/utils/app-insights'; import { buildUrl, formatSearchKeyword } from '@/utils/url'; import CreateForm from './components/CreateForm'; @@ -177,4 +177,4 @@ function Users() { ); } -export default withAppInsights(Users); +export default appInsightsReact.withAppInsights(Users); diff --git a/packages/console/src/utils/app-insights.ts b/packages/console/src/utils/app-insights.ts deleted file mode 100644 index ea5e5320d..000000000 --- a/packages/console/src/utils/app-insights.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ReactPlugin, withAITracking } from '@microsoft/applicationinsights-react-js'; -import { ApplicationInsights } from '@microsoft/applicationinsights-web'; -import type { Optional } from '@silverhand/essentials'; -import type { ComponentType } from 'react'; - -import { isCloud } from '@/consts/cloud'; - -/* eslint-disable @silverhand/fp/no-mutation, @silverhand/fp/no-let */ -let reactPlugin: Optional; -let appInsights: Optional; - -export const getAppInsights = () => appInsights; - -const initAppInsights = () => { - // The string needs to be normalized since it may contain '"' - const connectionString = process.env.APPLICATIONINSIGHTS_CONNECTION_STRING?.replace( - /^"?(.*)"?$/g, - '$1' - ); - - if (!isCloud || !connectionString) { - return; - } - - try { - // https://github.com/microsoft/applicationinsights-react-js#readme - reactPlugin = new ReactPlugin(); - appInsights = new ApplicationInsights({ - config: { - connectionString, - enableAutoRouteTracking: false, - extensions: [reactPlugin], - }, - }); - - appInsights.loadAppInsights(); - } catch (error: unknown) { - console.error('Unable to init ApplicationInsights:'); - console.error(error); - } -}; -/* eslint-enable @silverhand/fp/no-mutation, @silverhand/fp/no-let */ - -initAppInsights(); - -export const withAppInsights = (Component: ComponentType) => { - if (!isCloud || !reactPlugin) { - return Component; - } - - return withAITracking(reactPlugin, Component, undefined, 'appInsightsWrapper'); -}; diff --git a/packages/core/package.json b/packages/core/package.json index dc29fd6b8..49a016f10 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -27,6 +27,7 @@ "dependencies": { "@azure/storage-blob": "^12.13.0", "@koa/cors": "^4.0.0", + "@logto/app-insights": "workspace:^", "@logto/cli": "workspace:^", "@logto/connector-kit": "workspace:^", "@logto/core-kit": "workspace:^", @@ -36,7 +37,6 @@ "@logto/schemas": "workspace:^", "@logto/shared": "workspace:^", "@silverhand/essentials": "^2.5.0", - "applicationinsights": "^2.5.0", "aws-sdk": "^2.1329.0", "chalk": "^5.0.0", "clean-deep": "^3.4.0", diff --git a/packages/core/src/app/init.ts b/packages/core/src/app/init.ts index e41d32f30..da0b9737b 100644 --- a/packages/core/src/app/init.ts +++ b/packages/core/src/app/init.ts @@ -1,7 +1,7 @@ import fs from 'node:fs/promises'; import http2 from 'node:http2'; -import { appInsights } from '@logto/shared/app-insights'; +import { appInsights } from '@logto/app-insights/node.js'; import { toTitle, trySafe } from '@silverhand/essentials'; import chalk from 'chalk'; import type Koa from 'koa'; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 6e6301d5a..49b534e2b 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -8,8 +8,11 @@ import SystemContext from './tenants/SystemContext.js'; dotenv.config({ path: await findUp('.env', {}) }); -const { appInsights } = await import('@logto/shared/app-insights'); -appInsights.setup('logto'); +const { appInsights } = await import('@logto/app-insights/node.js'); + +if (appInsights.setup('logto')) { + console.debug('Initialized ApplicationInsights'); +} // Import after env has been configured const { loadConnectorFactories } = await import('./utils/connectors/index.js'); diff --git a/packages/core/src/middleware/koa-error-handler.ts b/packages/core/src/middleware/koa-error-handler.ts index 5f4714373..2a6e9cfef 100644 --- a/packages/core/src/middleware/koa-error-handler.ts +++ b/packages/core/src/middleware/koa-error-handler.ts @@ -1,5 +1,5 @@ +import { appInsights } from '@logto/app-insights/node.js'; import type { RequestErrorBody } from '@logto/schemas'; -import { appInsights } from '@logto/shared/app-insights'; import type { Middleware } from 'koa'; import { HttpError } from 'koa'; diff --git a/packages/demo-app/package.json b/packages/demo-app/package.json index 6d142e21a..195c77bca 100644 --- a/packages/demo-app/package.json +++ b/packages/demo-app/package.json @@ -27,7 +27,7 @@ "@silverhand/eslint-config-react": "3.0.0", "@silverhand/ts-config": "3.0.0", "@silverhand/ts-config-react": "3.0.0", - "@types/react": "^18.0.0", + "@types/react": "^18.0.31", "@types/react-dom": "^18.0.0", "buffer": "^5.7.1", "cross-env": "^7.0.3", diff --git a/packages/shared/package.json b/packages/shared/package.json index e8fe800f2..65c27d973 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -14,9 +14,6 @@ }, "./esm": { "import": "./lib/esm/index.js" - }, - "./app-insights": { - "import": "./lib/app-insights/index.js" } }, "publishConfig": { @@ -64,8 +61,5 @@ "find-up": "^6.3.0", "nanoid": "^4.0.0", "slonik": "^30.0.0" - }, - "optionalDependencies": { - "applicationinsights": "^2.5.0" } } diff --git a/packages/toolkit/core-kit/package.json b/packages/toolkit/core-kit/package.json index 812085299..bea4d955f 100644 --- a/packages/toolkit/core-kit/package.json +++ b/packages/toolkit/core-kit/package.json @@ -55,7 +55,7 @@ "@types/color": "^3.0.3", "@types/jest": "^29.4.0", "@types/node": "^18.11.18", - "@types/react": "^18.0.20", + "@types/react": "^18.0.31", "eslint": "^8.34.0", "jest": "^29.5.0", "lint-staged": "^13.0.0", diff --git a/packages/ui/package.json b/packages/ui/package.json index dbd3ce23b..63ec68f0f 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -40,7 +40,7 @@ "@testing-library/react": "^14.0.0", "@types/color": "^3.0.3", "@types/jest": "^29.4.0", - "@types/react": "^18.0.0", + "@types/react": "^18.0.31", "@types/react-dom": "^18.0.0", "@types/react-modal": "^3.13.1", "@types/react-router-dom": "^5.3.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4dcd480db..9e15cdca6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,6 +25,41 @@ importers: pg: 8.8.0 typescript: 5.0.2 + packages/app-insights: + specifiers: + '@microsoft/applicationinsights-react-js': ^3.4.1 + '@microsoft/applicationinsights-web': ^2.8.11 + '@silverhand/eslint-config': 3.0.0 + '@silverhand/essentials': ^2.5.0 + '@silverhand/ts-config': 3.0.0 + '@types/node': ^18.11.18 + '@types/react': ^18.0.31 + applicationinsights: ^2.5.0 + eslint: ^8.34.0 + history: ^5.3.0 + lint-staged: ^13.0.0 + prettier: ^2.8.2 + react: ^18.0.0 + tslib: ^2.4.1 + typescript: ^5.0.0 + dependencies: + '@microsoft/applicationinsights-react-js': 3.4.1_ru3n4sc2jwbij7oomq3xpksl5a + '@microsoft/applicationinsights-web': 2.8.11_tslib@2.4.1 + '@silverhand/essentials': 2.5.0 + applicationinsights: 2.5.0 + devDependencies: + '@silverhand/eslint-config': 3.0.0_f5srfdki6doc7lvdu3rizy6f2q + '@silverhand/ts-config': 3.0.0_typescript@5.0.2 + '@types/node': 18.11.18 + '@types/react': 18.0.31 + eslint: 8.34.0 + history: 5.3.0 + lint-staged: 13.0.0 + prettier: 2.8.4 + react: 18.2.0 + tslib: 2.4.1 + typescript: 5.0.2 + packages/cli: specifiers: '@logto/connector-kit': workspace:^ @@ -116,6 +151,7 @@ importers: packages/cloud: specifiers: + '@logto/app-insights': workspace:^ '@logto/cli': workspace:^ '@logto/connector-kit': workspace:^ '@logto/core-kit': workspace:^ @@ -133,7 +169,6 @@ importers: '@withtyped/postgres': ^0.8.1 '@withtyped/server': ^0.8.1 accepts: ^1.3.8 - applicationinsights: ^2.5.0 chalk: ^5.0.0 decamelize: ^6.0.0 dotenv: ^16.0.0 @@ -150,6 +185,7 @@ importers: typescript: ^5.0.0 zod: ^3.20.2 dependencies: + '@logto/app-insights': link:../app-insights '@logto/cli': link:../cli '@logto/connector-kit': link:../toolkit/connector-kit '@logto/core-kit': link:../toolkit/core-kit @@ -159,7 +195,6 @@ importers: '@withtyped/postgres': 0.8.1_@withtyped+server@0.8.1 '@withtyped/server': 0.8.1 accepts: 1.3.8 - applicationinsights: 2.5.0 chalk: 5.1.2 decamelize: 6.0.0 dotenv: 16.0.0 @@ -188,6 +223,7 @@ importers: packages/console: specifiers: '@fontsource/roboto-mono': ^4.5.7 + '@logto/app-insights': workspace:^ '@logto/connector-kit': workspace:^ '@logto/core-kit': workspace:^ '@logto/language-kit': workspace:^ @@ -196,8 +232,6 @@ importers: '@logto/react': 1.1.0 '@logto/schemas': workspace:^ '@mdx-js/react': ^1.6.22 - '@microsoft/applicationinsights-react-js': ^3.4.1 - '@microsoft/applicationinsights-web': ^2.8.11 '@parcel/compressor-brotli': 2.8.3 '@parcel/compressor-gzip': 2.8.3 '@parcel/core': 2.8.3 @@ -213,7 +247,7 @@ importers: '@types/color': ^3.0.3 '@types/mdx': ^2.0.1 '@types/mdx-js__react': ^1.5.5 - '@types/react': ^18.0.0 + '@types/react': ^18.0.31 '@types/react-dom': ^18.0.0 '@types/react-helmet': ^6.1.6 '@types/react-modal': ^3.13.1 @@ -270,6 +304,7 @@ importers: zod: ^3.20.2 devDependencies: '@fontsource/roboto-mono': 4.5.7 + '@logto/app-insights': link:../app-insights '@logto/connector-kit': link:../toolkit/connector-kit '@logto/core-kit': link:../toolkit/core-kit '@logto/language-kit': link:../toolkit/language-kit @@ -278,8 +313,6 @@ importers: '@logto/react': 1.1.0_react@18.2.0 '@logto/schemas': link:../schemas '@mdx-js/react': 1.6.22_react@18.2.0 - '@microsoft/applicationinsights-react-js': 3.4.1_ru3n4sc2jwbij7oomq3xpksl5a - '@microsoft/applicationinsights-web': 2.8.11_tslib@2.4.1 '@parcel/compressor-brotli': 2.8.3_@parcel+core@2.8.3 '@parcel/compressor-gzip': 2.8.3_@parcel+core@2.8.3 '@parcel/core': 2.8.3 @@ -295,7 +328,7 @@ importers: '@types/color': 3.0.3 '@types/mdx': 2.0.1 '@types/mdx-js__react': 1.5.5 - '@types/react': 18.0.15 + '@types/react': 18.0.31 '@types/react-dom': 18.0.6 '@types/react-helmet': 6.1.6 '@types/react-modal': 3.13.1 @@ -328,7 +361,7 @@ importers: prop-types: 15.8.1 react: 18.2.0 react-animate-height: 3.0.4_biqbaboplfbrettd7655fr4n2y - react-dnd: 16.0.0_3hx2ussxxho4jajbwrd6gq34qe + react-dnd: 16.0.0_o2wclmlv6kymw75psj4clbbe6a react-dnd-html5-backend: 16.0.0 react-dom: 18.2.0_react@18.2.0 react-dropzone: 14.2.3_react@18.2.0 @@ -336,7 +369,7 @@ importers: react-hook-form: 7.34.0_react@18.2.0 react-hot-toast: 2.2.0_npw22p3c4ehm7n7vxn2gqac44u react-i18next: 11.18.3_shxxmfhtk2bc4pbx5cyq3uoph4 - react-markdown: 8.0.0_3hx2ussxxho4jajbwrd6gq34qe + react-markdown: 8.0.0_o2wclmlv6kymw75psj4clbbe6a react-modal: 3.15.1_biqbaboplfbrettd7655fr4n2y react-paginate: 8.1.3_react@18.2.0 react-router-dom: 6.3.0_biqbaboplfbrettd7655fr4n2y @@ -355,6 +388,7 @@ importers: specifiers: '@azure/storage-blob': ^12.13.0 '@koa/cors': ^4.0.0 + '@logto/app-insights': workspace:^ '@logto/cli': workspace:^ '@logto/connector-kit': workspace:^ '@logto/core-kit': workspace:^ @@ -383,7 +417,6 @@ importers: '@types/semver': ^7.3.12 '@types/sinon': ^10.0.13 '@types/supertest': ^2.0.11 - applicationinsights: ^2.5.0 aws-sdk: ^2.1329.0 chalk: ^5.0.0 clean-deep: ^3.4.0 @@ -438,6 +471,7 @@ importers: dependencies: '@azure/storage-blob': 12.13.0 '@koa/cors': 4.0.0 + '@logto/app-insights': link:../app-insights '@logto/cli': link:../cli '@logto/connector-kit': link:../toolkit/connector-kit '@logto/core-kit': link:../toolkit/core-kit @@ -447,7 +481,6 @@ importers: '@logto/schemas': link:../schemas '@logto/shared': link:../shared '@silverhand/essentials': 2.5.0 - applicationinsights: 2.5.0 aws-sdk: 2.1329.0 chalk: 5.1.2 clean-deep: 3.4.0 @@ -539,7 +572,7 @@ importers: '@silverhand/eslint-config-react': 3.0.0 '@silverhand/ts-config': 3.0.0 '@silverhand/ts-config-react': 3.0.0 - '@types/react': ^18.0.0 + '@types/react': ^18.0.31 '@types/react-dom': ^18.0.0 buffer: ^5.7.1 cross-env: ^7.0.3 @@ -568,7 +601,7 @@ importers: '@silverhand/eslint-config-react': 3.0.0_xy6uwdposyujrlafdregyrl22m '@silverhand/ts-config': 3.0.0_typescript@5.0.2 '@silverhand/ts-config-react': 3.0.0_typescript@5.0.2 - '@types/react': 18.0.15 + '@types/react': 18.0.31 '@types/react-dom': 18.0.6 buffer: 5.7.1 cross-env: 7.0.3 @@ -756,7 +789,6 @@ importers: '@silverhand/ts-config': 3.0.0 '@types/jest': ^29.4.0 '@types/node': ^18.11.18 - applicationinsights: ^2.5.0 chalk: ^5.0.0 eslint: ^8.34.0 find-up: ^6.3.0 @@ -774,8 +806,6 @@ importers: find-up: 6.3.0 nanoid: 4.0.0 slonik: 30.1.2 - optionalDependencies: - applicationinsights: 2.5.0 devDependencies: '@logto/connector-kit': link:../toolkit/connector-kit '@silverhand/eslint-config': 3.0.0_f5srfdki6doc7lvdu3rizy6f2q @@ -827,7 +857,7 @@ importers: '@types/color': ^3.0.3 '@types/jest': ^29.4.0 '@types/node': ^18.11.18 - '@types/react': ^18.0.20 + '@types/react': ^18.0.31 color: ^4.2.3 eslint: ^8.34.0 jest: ^29.5.0 @@ -854,7 +884,7 @@ importers: '@types/color': 3.0.3 '@types/jest': 29.4.0 '@types/node': 18.11.18 - '@types/react': 18.0.26 + '@types/react': 18.0.31 eslint: 8.34.0 jest: 29.5.0_@types+node@18.11.18 lint-staged: 13.0.0 @@ -918,7 +948,7 @@ importers: '@testing-library/react': ^14.0.0 '@types/color': ^3.0.3 '@types/jest': ^29.4.0 - '@types/react': ^18.0.0 + '@types/react': ^18.0.31 '@types/react-dom': ^18.0.0 '@types/react-modal': ^3.13.1 '@types/react-router-dom': ^5.3.2 @@ -983,7 +1013,7 @@ importers: '@testing-library/react': 14.0.0_biqbaboplfbrettd7655fr4n2y '@types/color': 3.0.3 '@types/jest': 29.4.0 - '@types/react': 18.0.15 + '@types/react': 18.0.31 '@types/react-dom': 18.0.6 '@types/react-modal': 3.13.1 '@types/react-router-dom': 5.3.2 @@ -2609,7 +2639,7 @@ packages: '@microsoft/applicationinsights-shims': 2.0.2 '@microsoft/dynamicproto-js': 1.1.8 tslib: 2.4.1 - dev: true + dev: false /@microsoft/applicationinsights-channel-js/2.8.11_tslib@2.4.1: resolution: {integrity: sha512-DGDNzT4DMlSvUzWjA4y3tDg47+QYOPV+W07vlfdPwGgLwrl4n6Q4crrW8Y/IOpthHAKDU8rolSAUvP3NqxPi4Q==} @@ -2621,7 +2651,7 @@ packages: '@microsoft/applicationinsights-shims': 2.0.2 '@microsoft/dynamicproto-js': 1.1.8 tslib: 2.4.1 - dev: true + dev: false /@microsoft/applicationinsights-common/2.8.11_tslib@2.4.1: resolution: {integrity: sha512-Cxu4gRajkYv9buEtrcLGHK97AqGK62feN9jH9/JSjUSiSFhbnWtYvEg1EMqMI/P4pneu53yLJloITB+TKwmK7A==} @@ -2632,7 +2662,7 @@ packages: '@microsoft/applicationinsights-shims': 2.0.2 '@microsoft/dynamicproto-js': 1.1.8 tslib: 2.4.1 - dev: true + dev: false /@microsoft/applicationinsights-core-js/2.8.11_tslib@2.4.1: resolution: {integrity: sha512-6ScXplyb9Zb0K6TQRfqStm20j5lIe/Dslf65ozows6ibDcKkWl2ZdqzFhymVJZz1WRNpSyD4aA8qnqmslIER6g==} @@ -2642,7 +2672,7 @@ packages: '@microsoft/applicationinsights-shims': 2.0.2 '@microsoft/dynamicproto-js': 1.1.8 tslib: 2.4.1 - dev: true + dev: false /@microsoft/applicationinsights-dependencies-js/2.8.11_tslib@2.4.1: resolution: {integrity: sha512-eCjNouBvvnu+E3jLdfQgSIx3AUvmBDd14ZJNOjkvsaURhgRyWkBX3enT+RjrVrqyNQ74ZpHZpIJEqj90l28SsA==} @@ -2654,7 +2684,7 @@ packages: '@microsoft/applicationinsights-shims': 2.0.2 '@microsoft/dynamicproto-js': 1.1.8 tslib: 2.4.1 - dev: true + dev: false /@microsoft/applicationinsights-properties-js/2.8.11_tslib@2.4.1: resolution: {integrity: sha512-cuX8jwycBYX81SXmGTNK7JSJod3l8l3FIH0HPgPayCQy7CdHYlfKPTKE9q3I9qD1GO/3ER9yozuKpE+12Wk/2w==} @@ -2666,10 +2696,11 @@ packages: '@microsoft/applicationinsights-shims': 2.0.2 '@microsoft/dynamicproto-js': 1.1.8 tslib: 2.4.1 - dev: true + dev: false /@microsoft/applicationinsights-react-js/3.4.1_ru3n4sc2jwbij7oomq3xpksl5a: resolution: {integrity: sha512-oosMkymmkkulUdFcUbqKc64Li0KpItmV/pClOr4DCLAxbitCjHDkKdxodvpUzMHVs1ko9cHP360oc1QVXprhXQ==} + requiresBuild: true peerDependencies: history: '>= 4.10.1' react: '>= 17.0.1 || ^18.0.0' @@ -2682,11 +2713,11 @@ packages: history: 5.3.0 react: 18.2.0 tslib: 2.4.1 - dev: true + dev: false /@microsoft/applicationinsights-shims/2.0.2: resolution: {integrity: sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg==} - dev: true + dev: false /@microsoft/applicationinsights-web-snippet/1.0.1: resolution: {integrity: sha512-2IHAOaLauc8qaAitvWS+U931T+ze+7MNWrDHY47IENP5y2UA0vqJDu67kWZDdpCN1fFC77sfgfB+HV7SrKshnQ==} @@ -2694,6 +2725,7 @@ packages: /@microsoft/applicationinsights-web/2.8.11_tslib@2.4.1: resolution: {integrity: sha512-cLJl3MLQtvbwXU0hvFLl6S2/rIdoZKpZL8cvdaT0cXqd5XIiMbeUOxWHLf2hxT8IlIeVlu5nnFILeRYOFZowvw==} + requiresBuild: true peerDependencies: tslib: '*' dependencies: @@ -2706,11 +2738,11 @@ packages: '@microsoft/applicationinsights-shims': 2.0.2 '@microsoft/dynamicproto-js': 1.1.8 tslib: 2.4.1 - dev: true + dev: false /@microsoft/dynamicproto-js/1.1.8: resolution: {integrity: sha512-j4ZgOZRtX0LTUgKq+4tRQotgwH03HH/mLkYbcgFBBJ9XKTDc4NIGzZeam2UQMzwz+5IVN0SXexNbbsz5B0b/og==} - dev: true + dev: false /@mischnic/json-sourcemap/0.1.0: resolution: {integrity: sha512-dQb3QnfNqmQNYA4nFSN/uLaByIic58gOXq4Y4XqLOWmOrw73KmJPt/HLyG0wvn1bnR6mBKs/Uwvkh+Hns1T0XA==} @@ -3647,7 +3679,7 @@ packages: '@peculiar/asn1-schema': 2.1.0 '@peculiar/json-schema': 1.1.12 pvtsutils: 1.2.2 - tslib: 2.3.1 + tslib: 2.4.1 webcrypto-core: 1.7.3 dev: true @@ -4459,7 +4491,7 @@ packages: /@types/mdx-js__react/1.5.5: resolution: {integrity: sha512-k8pnaP6JXVlQh18HgL5X6sYFNC/qZnzO7R2+HsmwrwUd+JnnsU0d9lyyT0RQrHg1anxDU36S98TI/fsGtmYqqg==} dependencies: - '@types/react': 18.0.15 + '@types/react': 18.0.31 dev: true /@types/mdx/2.0.1: @@ -4549,26 +4581,26 @@ packages: /@types/react-dom/18.0.6: resolution: {integrity: sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA==} dependencies: - '@types/react': 18.0.15 + '@types/react': 18.0.31 dev: true /@types/react-helmet/6.1.6: resolution: {integrity: sha512-ZKcoOdW/Tg+kiUbkFCBtvDw0k3nD4HJ/h/B9yWxN4uDO8OkRksWTO+EL+z/Qu3aHTeTll3Ro0Cc/8UhwBCMG5A==} dependencies: - '@types/react': 18.0.26 + '@types/react': 18.0.31 dev: true /@types/react-modal/3.13.1: resolution: {integrity: sha512-iY/gPvTDIy6Z+37l+ibmrY+GTV4KQTHcCyR5FIytm182RQS69G5ps4PH2FxtC7bAQ2QRHXMevsBgck7IQruHNg==} dependencies: - '@types/react': 18.0.15 + '@types/react': 18.0.31 dev: true /@types/react-router-dom/5.3.2: resolution: {integrity: sha512-ELEYRUie2czuJzaZ5+ziIp9Hhw+juEw8b7C11YNA4QdLCVbQ3qLi2l4aq8XnlqM7V31LZX8dxUuFUCrzHm6sqQ==} dependencies: '@types/history': 4.7.9 - '@types/react': 18.0.26 + '@types/react': 18.0.31 '@types/react-router': 5.1.17 dev: true @@ -4576,25 +4608,17 @@ packages: resolution: {integrity: sha512-RNSXOyb3VyRs/EOGmjBhhGKTbnN6fHWvy5FNLzWfOWOGjgVUKqJZXfpKzLmgoU8h6Hj8mpALj/mbXQASOb92wQ==} dependencies: '@types/history': 4.7.11 - '@types/react': 18.0.26 + '@types/react': 18.0.31 dev: true /@types/react-syntax-highlighter/15.5.1: resolution: {integrity: sha512-+yD6D8y21JqLf89cRFEyRfptVMqo2ROHyAlysRvFwT28gT5gDo3KOiXHwGilHcq9y/OKTjlWK0f/hZUicrBFPQ==} dependencies: - '@types/react': 18.0.15 + '@types/react': 18.0.31 dev: true - /@types/react/18.0.15: - resolution: {integrity: sha512-iz3BtLuIYH1uWdsv6wXYdhozhqj20oD4/Hk2DNXIn1kFsmp9x8d9QB6FnPhfkbhd2PgEONt9Q1x/ebkwjfFLow==} - dependencies: - '@types/prop-types': 15.7.4 - '@types/scheduler': 0.16.2 - csstype: 3.0.11 - dev: true - - /@types/react/18.0.26: - resolution: {integrity: sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==} + /@types/react/18.0.31: + resolution: {integrity: sha512-EEG67of7DsvRDU6BLLI0p+k1GojDLz9+lZsnCpCRTa/lOokvyPBvp8S5x+A24hME3yyQuIipcP70KJ6H7Qupww==} dependencies: '@types/prop-types': 15.7.4 '@types/scheduler': 0.16.2 @@ -8072,7 +8096,6 @@ packages: resolution: {integrity: sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==} dependencies: '@babel/runtime': 7.19.4 - dev: true /hoist-non-react-statics/3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} @@ -10287,7 +10310,6 @@ packages: hasBin: true dependencies: js-tokens: 4.0.0 - dev: true /lower-case/2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} @@ -12384,7 +12406,7 @@ packages: dnd-core: 16.0.0 dev: true - /react-dnd/16.0.0_3hx2ussxxho4jajbwrd6gq34qe: + /react-dnd/16.0.0_o2wclmlv6kymw75psj4clbbe6a: resolution: {integrity: sha512-RCoeWRWhuwSoqdLaJV8N/weARLyXqsf43OC3QiBWPORIIGGovF/EqI8ckf14ca3bl6oZNI/igtxX49+IDmNDeQ==} peerDependencies: '@types/hoist-non-react-statics': '>= 3.3.1' @@ -12401,7 +12423,7 @@ packages: dependencies: '@react-dnd/invariant': 4.0.0 '@react-dnd/shallowequal': 4.0.0 - '@types/react': 18.0.15 + '@types/react': 18.0.31 dnd-core: 16.0.0 fast-deep-equal: 3.1.3 hoist-non-react-statics: 3.3.2 @@ -12509,14 +12531,14 @@ packages: resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} dev: true - /react-markdown/8.0.0_3hx2ussxxho4jajbwrd6gq34qe: + /react-markdown/8.0.0_o2wclmlv6kymw75psj4clbbe6a: resolution: {integrity: sha512-qbrWpLny6Ef2xHqnYqtot948LXP+4FtC+MWIuaN1kvSnowM+r1qEeEHpSaU0TDBOisQuj+Qe6eFY15cNL3gLAw==} peerDependencies: '@types/react': '>=16' react: '>=16 || ^18.0.0' dependencies: '@types/hast': 2.3.4 - '@types/react': 18.0.15 + '@types/react': 18.0.31 '@types/unist': 2.0.6 comma-separated-tokens: 2.0.2 hast-util-whitespace: 2.0.0 @@ -12695,7 +12717,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: loose-envify: 1.4.0 - dev: true /read-pkg-up/7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} @@ -13473,7 +13494,7 @@ packages: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} dependencies: dot-case: 3.0.4 - tslib: 2.4.0 + tslib: 2.4.1 dev: false /snakecase-keys/5.4.4: @@ -14324,14 +14345,6 @@ packages: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} dev: true - /tslib/2.3.1: - resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==} - dev: true - - /tslib/2.4.0: - resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} - dev: false - /tslib/2.4.1: resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==}