deps: update webui deps

This commit is contained in:
master 2025-04-25 02:21:20 +08:00
parent eb8f0be004
commit b20f7cd1ad
11 changed files with 2644 additions and 2263 deletions

View File

@ -9,7 +9,8 @@
"preview": "rsbuild preview"
},
"dependencies": {
"@abraham/reflection": "^0.12.0",
"@abraham/reflection": "^0.13.0",
"@apollo/client": "^3.13.8",
"@codemirror/language": "6.0.0",
"@corvu/drawer": "^0.2.3",
"@corvu/otp-field": "^0.1.4",
@ -53,18 +54,19 @@
"cmdk": "^1.1.1",
"date-fns": "^4.1.0",
"embla-carousel-react": "^8.6.0",
"graphiql": "^3.8.3",
"graphiql": "^4.0.2",
"graphql": "^16.11.0",
"input-otp": "^1.4.2",
"jotai": "^2.12.3",
"jotai-signal": "^0.9.0",
"lucide-react": "^0.503.0",
"lucide-react": "^0.508.0",
"next-themes": "^0.4.6",
"oidc-client-rx": "0.1.0-alpha.9",
"react": "^19.1.0",
"react-day-picker": "8.10.1",
"react-day-picker": "9.6.7",
"react-dom": "^19.1.0",
"react-hook-form": "^7.56.0",
"react-resizable-panels": "^2.1.7",
"react-resizable-panels": "^3.0.0",
"recharts": "^2.15.3",
"rxjs": "^7.8.2",
"sonner": "^2.0.3",
@ -72,8 +74,7 @@
"tailwindcss": "^4.0.6",
"tw-animate-css": "^1.2.7",
"type-fest": "^4.40.0",
"vaul": "^1.1.2",
"zod": "^3.24.3"
"vaul": "^1.1.2"
},
"devDependencies": {
"@rsbuild/core": "^1.2.15",

View File

@ -1,83 +1,61 @@
import { UnreachableError } from '@/infra/errors/common';
import { AuthService } from '@/domains/auth/auth.service';
import type { Injector, Provider } from '@outposts/injection-js';
import type { AnyRouter } from '@tanstack/react-router';
import {
CHECK_AUTH_RESULT_EVENT,
type CheckAuthResultEventType,
OidcSecurityService,
provideAuth as provideOidcAuth,
withCheckAuthResultEvent,
withDefaultFeatures,
} from 'oidc-client-rx';
import { withTanstackRouter } from 'oidc-client-rx/adapters/@tanstack/react-router';
import { NEVER, type Observable, map, of } from 'rxjs';
import { AppAuthMethod, AuthMethodEnum, buildOidcConfig } from './config';
import type { Observable } from 'rxjs';
import {
AppAuthMethod,
AuthMethodEnum,
type AuthMethodType,
buildOidcConfig,
} from './config';
export function provideAuth(router: AnyRouter): Provider[] {
const providers: Provider[] = [AuthService];
if (AppAuthMethod === AuthMethodEnum.OIDC) {
return provideOidcAuth(
{
config: buildOidcConfig(),
},
withDefaultFeatures({
router: { enabled: false },
securityStorage: { type: 'local-storage' },
}),
withTanstackRouter(router),
withCheckAuthResultEvent()
providers.push(
...provideOidcAuth(
{
config: buildOidcConfig(),
},
withDefaultFeatures({
router: { enabled: false },
securityStorage: { type: 'local-storage' },
}),
withTanstackRouter(router),
withCheckAuthResultEvent()
)
);
}
return [];
return providers;
}
export function setupAuthContext(injector: Injector) {
if (AppAuthMethod === AuthMethodEnum.OIDC) {
const oidcSecurityService = injector.get(OidcSecurityService);
oidcSecurityService.checkAuth().subscribe();
}
const { authService } = authContextFromInjector(injector);
authService.setup();
}
export interface OidcAuthContext {
type: typeof AuthMethodEnum.OIDC;
oidcSecurityService: OidcSecurityService;
export interface AuthContext {
type: AuthMethodType;
authService: AuthService;
isAuthenticated$: Observable<boolean>;
userData$: Observable<{}>;
checkAuthResultEvent$: Observable<CheckAuthResultEventType>;
}
export interface BasicAuthContext {
type: typeof AuthMethodEnum.BASIC;
isAuthenticated$: Observable<true>;
userData$: Observable<{}>;
checkAuthResultEvent$: Observable<CheckAuthResultEventType>;
}
export type AuthContext = OidcAuthContext | BasicAuthContext;
const BASIC_AUTH_IS_AUTHENTICATED$ = of(true) as Observable<true>;
const BASIC_AUTH_USER_DATA$ = of({});
export function authContextFromInjector(injector: Injector): AuthContext {
if (AppAuthMethod === AuthMethodEnum.OIDC) {
const oidcSecurityService = injector.get(OidcSecurityService)!;
return {
type: AuthMethodEnum.OIDC,
oidcSecurityService: injector.get(OidcSecurityService),
isAuthenticated$: oidcSecurityService.isAuthenticated$.pipe(
map((s) => s.isAuthenticated)
),
userData$: oidcSecurityService.userData$.pipe(map((s) => s.userData)),
checkAuthResultEvent$: injector.get(CHECK_AUTH_RESULT_EVENT),
};
}
if (AppAuthMethod === AuthMethodEnum.BASIC) {
return {
type: AuthMethodEnum.BASIC,
isAuthenticated$: BASIC_AUTH_IS_AUTHENTICATED$,
userData$: BASIC_AUTH_USER_DATA$,
checkAuthResultEvent$: NEVER,
};
}
throw new UnreachableError('Invalid auth method');
const authService = injector.get(AuthService);
return {
type: AppAuthMethod,
authService,
isAuthenticated$: authService.isAuthenticated$,
userData$: authService.userData$,
checkAuthResultEvent$: authService.checkAuthResultEvent$,
};
}

View File

@ -0,0 +1,53 @@
import { AppAuthMethod, AuthMethodEnum } from '@/app/auth/config';
import { injectInjector } from '@/infra/di/inject';
import { Injectable, type Injector } from '@outposts/injection-js';
import {
CHECK_AUTH_RESULT_EVENT,
type CheckAuthResultEventType,
OidcSecurityService,
} from 'oidc-client-rx';
import { NEVER, type Observable, map, of } from 'rxjs';
const BASIC_AUTH_IS_AUTHENTICATED$ = of(true) as Observable<true>;
const BASIC_AUTH_USER_DATA$ = of({});
@Injectable()
export class AuthService {
private injector: Injector = injectInjector();
oidcSecurityService: OidcSecurityService | undefined;
checkAuthResultEvent$: Observable<CheckAuthResultEventType>;
constructor() {
if (AppAuthMethod === 'oidc') {
this.oidcSecurityService = this.injector.get(OidcSecurityService);
this.checkAuthResultEvent$ = this.injector.get(CHECK_AUTH_RESULT_EVENT);
} else {
this.checkAuthResultEvent$ = NEVER;
}
}
setup() {
if (AppAuthMethod === AuthMethodEnum.OIDC) {
this.oidcSecurityService!.checkAuth().subscribe();
}
}
get isAuthenticated$() {
return (
this.oidcSecurityService?.isAuthenticated$.pipe(
map((s) => s.isAuthenticated)
) ?? BASIC_AUTH_IS_AUTHENTICATED$
);
}
get userData$() {
return (
this.oidcSecurityService?.userData$?.pipe(map((s) => s.userData)) ??
BASIC_AUTH_USER_DATA$
);
}
getAccessToken(): Observable<string | undefined> {
return this.oidcSecurityService?.getAccessToken() ?? of(undefined);
}
}

View File

@ -0,0 +1,5 @@
import { type InjectionToken, Injector, inject } from '@outposts/injection-js';
export function injectInjector(): Injector {
return inject(Injector as any as InjectionToken<Injector>);
}

View File

@ -1,19 +1,21 @@
import * as React from "react"
import React from 'react';
const MOBILE_BREAKPOINT = 768
const MOBILE_BREAKPOINT = 768;
export function useIsMobile() {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
undefined
);
React.useEffect(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
const onChange = () => {
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
}
mql.addEventListener("change", onChange)
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
return () => mql.removeEventListener("change", onChange)
}, [])
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
};
mql.addEventListener('change', onChange);
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
return () => mql.removeEventListener('change', onChange);
}, []);
return !!isMobile
return !!isMobile;
}

View File

@ -0,0 +1,7 @@
import { Injectable, inject } from '@outposts/injection-js';
import { OidcSecurityService } from 'oidc-client-rx';
@Injectable()
export class HttpService {
authService = inject(OidcSecurityService);
}

View File

@ -48,16 +48,16 @@ const rootElement = document.getElementById('root');
const App = () => {
return (
<Suspense>
<InjectorProvider injector={injector}>
<InjectorProvider injector={injector}>
<Suspense>
<RouterProvider
router={router}
context={{
injector,
}}
/>
</InjectorProvider>
</Suspense>
</Suspense>
</InjectorProvider>
);
};

View File

@ -1,10 +1,9 @@
import { useAuth } from '@/app/auth/hooks';
import { type Fetcher, createGraphiQLFetcher } from '@graphiql/toolkit';
import { createLazyFileRoute } from '@tanstack/react-router';
import GraphiQL from 'graphiql';
import { GraphiQL } from 'graphiql';
import { useCallback } from 'react';
import 'graphiql/graphiql.css';
import { AuthMethodEnum } from '@/app/auth/config';
import { firstValueFrom } from 'rxjs';
export const Route = createLazyFileRoute('/_app/playground/graphql-api')({
@ -16,12 +15,9 @@ function PlaygroundGraphQLApiRouteComponent() {
const fetcher: Fetcher = useCallback(
async (props) => {
const accessToken =
authContext.type === AuthMethodEnum.OIDC
? await firstValueFrom(
authContext.oidcSecurityService.getAccessToken()
)
: undefined;
const accessToken = await firstValueFrom(
authContext.authService.getAccessToken()
);
return createGraphiQLFetcher({
url: '/api/graphql',
headers: accessToken
@ -31,11 +27,7 @@ function PlaygroundGraphQLApiRouteComponent() {
: undefined,
})(props);
},
[
authContext.type,
// @ts-ignore
authContext?.oidcSecurityService?.getAccessToken,
]
[authContext.authService.getAccessToken]
);
return (

View File

@ -7,6 +7,7 @@
"linter": {
"rules": {
"style": {
"noParameterProperties": "off",
"noNonNullAssertion": "off"
},
"security": {

View File

@ -14,7 +14,7 @@
"bump-deps": "npx --yes npm-check-updates --deep -u -x react-day-picker && pnpm install",
"clean": "git clean -xdf node_modules"
},
"packageManager": "pnpm@10.6.1",
"packageManager": "pnpm@10.10.0",
"engines": {
"node": ">=22"
},
@ -22,23 +22,9 @@
"@auto-it/all-contributors": "^11.3.0",
"@auto-it/first-time-contributor": "^11.3.0",
"@biomejs/biome": "1.9.4",
"@types/node": "^22.13.8",
"tsx": "^4.19.2",
"typescript": "^5.8.2",
"ultracite": "^4.1.15"
},
"overrides": {
"@headlessui/react": "^2.2.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"date-fns": "^4.1.0"
},
"pnpm": {
"overrides": {
"@headlessui/react": "^2.2.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"date-fns": "^4.1.0"
}
"@types/node": "^22.15.16",
"tsx": "^4.19.4",
"typescript": "^5.8.3",
"ultracite": "^4.2.4"
}
}

4658
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff