✖ eslint --cache --cache-location ./node_modules/.cache/.eslintcache --fix:
Warning: React version not specified in eslint-plugin-react settings. See https://github.com/jsx-eslint/eslint-plugin-react#configuration .
/home/andrew/CODE/JS/React/IdeaNick/webapp/src/lib/pageWrapper.tsx
24:29 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
25:39 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
25:44 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
58:45 error The `{}` ("empty object") type allows any non-nullish value, including literals like `0` and `""`.
- If that's what you want, disable this lint rule with an inline comment or configure the 'allowObjectTypes' rule option.
- If you want a type meaning "any object", you probably want `object` instead.
- If you want a type meaning "any value", you probably want `unknown` instead @typescript-eslint/no-empty-object-type
127:56 error The `{}` ("empty object") type allows any non-nullish value, including literals like `0` and `""`.
- If that's what you want, disable this lint rule with an inline comment or configure the 'allowObjectTypes' rule option.
- If you want a type meaning "any object", you probably want `object` instead.
- If you want a type meaning "any value", you probably want `unknown` instead @typescript-eslint/no-empty-object-type
131:12 error Component definition is missing display name react/display-name
✖ 6 problems (6 errors, 0 warnings)
import { type UseTRPCQueryResult, type UseTRPCQuerySuccessResult } from '@trpc/react-query/shared'
import React, { useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { ErrorPageComponent } from '../components/ErrorPageComponent'
import { NotFoundPage } from '../pages/other/NotFoundPage'
import { useAppContext, type AppContext } from './ctx'
import { getAllIdeasRoute } from './routes'
class CheckExistsError extends Error {}
const checkExistsFn = <T,>(value: T, message?: string): NonNullable<T> => {
if (!value) {
throw new CheckExistsError(message)
}
return value
}
class CheckAccessError extends Error {}
const checkAccessFn = <T,>(value: T, message?: string): void => {
if (!value) {
throw new CheckAccessError(message)
}
}
type Props = Record<string, any>
type QueryResult = UseTRPCQueryResult<any, any>
type QuerySuccessResult<TQueryResult extends QueryResult> = UseTRPCQuerySuccessResult<
NonNullable<TQueryResult['data']>,
null
>
type HelperProps<TQueryResult extends QueryResult | undefined> = {
ctx: AppContext
queryResult: TQueryResult extends QueryResult ? QuerySuccessResult<TQueryResult> : undefined
}
type SetPropsProps<TQueryResult extends QueryResult | undefined> = HelperProps<TQueryResult> & {
checkExists: typeof checkExistsFn
checkAccess: typeof checkAccessFn
}
type PageWrapperProps<TProps extends Props, TQueryResult extends QueryResult | undefined> = {
redirectAuthorized?: boolean
authorizedOnly?: boolean
authorizedOnlyTitle?: string
authorizedOnlyMessage?: string
checkAccess?: (helperProps: HelperProps<TQueryResult>) => boolean
checkAccessTitle?: string
checkAccessMessage?: string
checkExists?: (helperProps: HelperProps<TQueryResult>) => boolean
checkExistsTitle?: string
checkExistsMessage?: string
useQuery?: () => TQueryResult
setProps?: (setPropsProps: SetPropsProps<TQueryResult>) => TProps
Page: React.FC<TProps>
}
const PageWrapper = <TProps extends Props = {}, TQueryResult extends QueryResult | undefined = undefined>({
authorizedOnly,
authorizedOnlyTitle = 'Please, Authorize',
authorizedOnlyMessage = 'This page is available only for authorized users',
redirectAuthorized,
checkAccess,
checkAccessTitle = 'Access Denied',
checkAccessMessage = 'You have no access to this page',
checkExists,
checkExistsTitle,
checkExistsMessage,
useQuery,
setProps,
Page,
}: PageWrapperProps<TProps, TQueryResult>) => {
const navigate = useNavigate()
const ctx = useAppContext()
const queryResult = useQuery?.()
const redirectNeeded = redirectAuthorized && ctx.me
useEffect(() => {
if (redirectNeeded) {
navigate(getAllIdeasRoute(), { replace: true })
}
}, [redirectNeeded, navigate])
if (queryResult?.isLoading || queryResult?.isFetching || redirectNeeded) {
return <p>Loading...</p>
}
if (queryResult?.isError) {
return <ErrorPageComponent message={queryResult.error.message} />
}
if (authorizedOnly && !ctx.me) {
return <ErrorPageComponent title={authorizedOnlyTitle} message={authorizedOnlyMessage} />
}
const helperProps = { ctx, queryResult: queryResult as never }
if (checkAccess) {
const accessDenied = !checkAccess(helperProps)
if (accessDenied) {
return <ErrorPageComponent title={checkAccessTitle} message={checkAccessMessage} />
}
}
if (checkExists) {
const notExists = !checkExists(helperProps)
if (notExists) {
return <NotFoundPage title={checkExistsTitle} message={checkExistsMessage} />
}
}
try {
const props = setProps?.({ ...helperProps, checkExists: checkExistsFn, checkAccess: checkAccessFn }) as TProps
return <Page {...props} />
} catch (error) {
if (error instanceof CheckExistsError) {
return <NotFoundPage title={checkExistsTitle} message={error.message || checkExistsMessage} />
}
if (error instanceof CheckAccessError) {
return <ErrorPageComponent title={checkAccessTitle} message={error.message || checkAccessMessage} />
}
throw error
}
}
export const withPageWrapper = <TProps extends Props = {}, TQueryResult extends QueryResult | undefined = undefined>(
pageWrapperProps: Omit<PageWrapperProps<TProps, TQueryResult>, 'Page'>
) => {
return (Page: PageWrapperProps<TProps, TQueryResult>['Page']) => {
return () => <PageWrapper {...pageWrapperProps} Page={Page} />
}
}