implemented identity, updated session, added 'workings' list
added paginated querying, added 'common'
This commit is contained in:
parent
027deba422
commit
6ada519e06
36 changed files with 1422 additions and 279 deletions
159
app/client/components/Editor.tsx
Normal file
159
app/client/components/Editor.tsx
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
import { Card, Heading, SystemStyleObject } from '@chakra-ui/react';
|
||||
import EditorJS, { EditorConfig } from '@editorjs/editorjs';
|
||||
import Header from '@editorjs/header';
|
||||
import List from '@editorjs/list';
|
||||
import Quote from '@editorjs/quote';
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
||||
// @ts-ignore
|
||||
import Link from '@coolbytes/editorjs-link';
|
||||
|
||||
export function Editor({ initialData }: { initialData?: EditorConfig['data'] }) {
|
||||
const ejInstance = useRef<EditorJS | undefined | null>();
|
||||
|
||||
const initEditor = () => {
|
||||
const editor = new EditorJS({
|
||||
holder: 'editorjs',
|
||||
onReady: () => {
|
||||
ejInstance.current = editor;
|
||||
},
|
||||
autofocus: true,
|
||||
data: initialData,
|
||||
// onChange: async () => {
|
||||
// const content = await editor.saver.save();
|
||||
// },
|
||||
tools: {
|
||||
header: Header,
|
||||
list: List,
|
||||
link: Link,
|
||||
quote: Quote
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (ejInstance.current === null) {
|
||||
initEditor();
|
||||
}
|
||||
|
||||
return () => {
|
||||
ejInstance?.current?.destroy();
|
||||
ejInstance.current = null;
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card.Root
|
||||
variant={'subtle'}
|
||||
width="100%"
|
||||
maxWidth="840px"
|
||||
minHeight="sm"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
>
|
||||
<Card.Header>
|
||||
<Heading textAlign="center">Editor</Heading>
|
||||
</Card.Header>
|
||||
<Card.Body
|
||||
width="90%"
|
||||
css={{
|
||||
'& *': {
|
||||
fontSize: 'revert',
|
||||
fontWeight: 'revert'
|
||||
},
|
||||
...editorJsStyles
|
||||
}}
|
||||
>
|
||||
<div className="editorjs" id="editorjs"></div>
|
||||
</Card.Body>
|
||||
</Card.Root>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const editorJsStyles:
|
||||
| SystemStyleObject
|
||||
| Omit<Array<SystemStyleObject | undefined>, keyof any[]>
|
||||
| undefined = {
|
||||
'& .ce-block--selected .ce-block__content, \
|
||||
& .ce-inline-toolbar, \
|
||||
& .codex-editor--narrow .ce-toolbox, \
|
||||
& .ce-conversion-toolbar, \
|
||||
& .ce-settings, \
|
||||
& .ce-settings__button, \
|
||||
& .ce-toolbar__settings-btn, \
|
||||
& .cdx-button, \
|
||||
& .ce-popover': {
|
||||
background: 'colorPalette.500',
|
||||
border: 'none'
|
||||
},
|
||||
|
||||
'& .ce-inline-tool, \
|
||||
& .ce-conversion-toolbar__label, \
|
||||
& .ce-toolbox__button, \
|
||||
& .cdx-settings-button, \
|
||||
& .ce-toolbar__plus': {
|
||||
color: 'colorPalette.500'
|
||||
},
|
||||
|
||||
'& ::selection': {
|
||||
background: 'colorPalette.500'
|
||||
},
|
||||
|
||||
'& .cdx-settings-button:hover, \
|
||||
& .ce-settings__button:hover, \
|
||||
& .ce-toolbox__button--active, \
|
||||
& .ce-toolbox__button:hover, \
|
||||
& .cdx-button:hover, \
|
||||
& .ce-inline-toolbar__dropdown:hover, \
|
||||
& .ce-inline-tool:hover, \
|
||||
& .ce-popover__item:hover, \
|
||||
& .ce-toolbar__settings-btn:hover': {
|
||||
background: 'colorPalette.500',
|
||||
color: 'fg'
|
||||
},
|
||||
|
||||
'& .cdx-notify--error': {
|
||||
background: 'red !important'
|
||||
},
|
||||
|
||||
'& .cdx-notify__cross::after, & .cdx-notify__cross::before': {
|
||||
background: 'white'
|
||||
},
|
||||
|
||||
'& .ce-toolbar__plus:hover, \
|
||||
& .ce-popover__container': {
|
||||
backgroundColor: 'bg.emphasized',
|
||||
color: 'colorPalette.500',
|
||||
border: 'none'
|
||||
},
|
||||
|
||||
'& .ce-popover-item:hover:not(.ce-popover-item--no-hover)': {
|
||||
backgroundColor: 'colorPalette.500',
|
||||
color: 'fg'
|
||||
},
|
||||
|
||||
'& .cdx-search-field': {
|
||||
background: 'bg.muted',
|
||||
color: 'fg',
|
||||
border: 'none'
|
||||
},
|
||||
|
||||
'& .ce-popover-item__title, \
|
||||
& .ce-popover-item__icon': {
|
||||
color: 'fg'
|
||||
},
|
||||
|
||||
'& .ce-popover-item-separator': {
|
||||
color: 'bg.muted'
|
||||
},
|
||||
|
||||
'& .ce-toolbar__settings-btn': {
|
||||
color: 'white'
|
||||
},
|
||||
|
||||
'& .ce-toolbar__settings-btn:hover': {
|
||||
color: 'black'
|
||||
}
|
||||
};
|
||||
44
app/client/components/Pagination.tsx
Normal file
44
app/client/components/Pagination.tsx
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import { ButtonGroup, Pagination as ChakraPagination, IconButton } from '@chakra-ui/react';
|
||||
import { LuChevronLeft, LuChevronRight } from 'react-icons/lu';
|
||||
|
||||
export function Pagination({
|
||||
total,
|
||||
page,
|
||||
setPage,
|
||||
pageSize = 5
|
||||
}: {
|
||||
total: number;
|
||||
page: number;
|
||||
setPage: (value: number) => void;
|
||||
pageSize?: number;
|
||||
}) {
|
||||
return (
|
||||
<ChakraPagination.Root
|
||||
count={total}
|
||||
page={page}
|
||||
pageSize={pageSize}
|
||||
onPageChange={e => setPage(e.page)}
|
||||
defaultPage={1}
|
||||
>
|
||||
<ButtonGroup variant="ghost" size="sm">
|
||||
<ChakraPagination.PrevTrigger asChild>
|
||||
<IconButton>
|
||||
<LuChevronLeft />
|
||||
</IconButton>
|
||||
</ChakraPagination.PrevTrigger>
|
||||
|
||||
<ChakraPagination.Items
|
||||
render={page => (
|
||||
<IconButton variant={{ base: 'ghost', _selected: 'solid' }}>{page.value}</IconButton>
|
||||
)}
|
||||
/>
|
||||
|
||||
<ChakraPagination.NextTrigger asChild>
|
||||
<IconButton>
|
||||
<LuChevronRight />
|
||||
</IconButton>
|
||||
</ChakraPagination.NextTrigger>
|
||||
</ButtonGroup>
|
||||
</ChakraPagination.Root>
|
||||
);
|
||||
}
|
||||
14
app/client/components/WorkingList.tsx
Normal file
14
app/client/components/WorkingList.tsx
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { List } from '@chakra-ui/react';
|
||||
import { WorkingCardProps, WorkingListCard } from './WorkingListCard';
|
||||
|
||||
export function WorkingList({ workingsList }: { workingsList: WorkingCardProps[] }) {
|
||||
return (
|
||||
<List.Root variant="plain" gap={4}>
|
||||
{workingsList.map(workingData => (
|
||||
<List.Item key={workingData.id}>
|
||||
<WorkingListCard {...workingData} />
|
||||
</List.Item>
|
||||
))}
|
||||
</List.Root>
|
||||
);
|
||||
}
|
||||
115
app/client/components/WorkingListCard.tsx
Normal file
115
app/client/components/WorkingListCard.tsx
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
import { Badge, BadgeProps, Box, Card, Heading, Icon, Link, Stack, Text } from '@chakra-ui/react';
|
||||
import { WorkingProgressStatus } from '@generated/types';
|
||||
import { ReactNode } from 'react';
|
||||
import { WorkingProgressStatusBadge } from './WorkingProgressStatusBadge';
|
||||
import { WorkingRatingBadge } from './WorkingRatingBadge';
|
||||
|
||||
export interface WorkingCardProps {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
author: { id: string; username: string };
|
||||
progressStatus: WorkingProgressStatus;
|
||||
updatedAt: string;
|
||||
chaptersTotal: number;
|
||||
wordsTotal: number;
|
||||
ratingTotal: number;
|
||||
reviewsTotal: number;
|
||||
}
|
||||
|
||||
export function WorkingListCard({
|
||||
title,
|
||||
description,
|
||||
author,
|
||||
progressStatus,
|
||||
updatedAt,
|
||||
chaptersTotal,
|
||||
wordsTotal,
|
||||
ratingTotal,
|
||||
reviewsTotal
|
||||
}: WorkingCardProps) {
|
||||
return (
|
||||
<Card.Root width="100%" variant="elevated">
|
||||
<Card.Body>
|
||||
<Stack>
|
||||
<Stack direction="row" justifyContent="space-between">
|
||||
<Link>
|
||||
<Heading size="lg">{title}</Heading>
|
||||
</Link>
|
||||
|
||||
<Stack direction="row" justifyContent="center" alignItems="center">
|
||||
<WorkingRatingBadge ratingTotal={ratingTotal} />
|
||||
<IconBadge backgroundColor="orange.400" iconClass="nf nf-oct-comment">
|
||||
<Text>{reviewsTotal}</Text>
|
||||
</IconBadge>
|
||||
<WorkingProgressStatusBadge progressStatus={progressStatus} />
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<Stack>
|
||||
<Stack direction="row">
|
||||
<Text>by:</Text>
|
||||
<Link>{author.username}</Link>
|
||||
</Stack>
|
||||
|
||||
<Stack direction="row">
|
||||
<Box>
|
||||
<Badge size="md" variant="solid">
|
||||
<Stack direction="row">
|
||||
<Text>last updated:</Text>
|
||||
<Text>{updatedAt}</Text>
|
||||
</Stack>
|
||||
</Badge>
|
||||
</Box>
|
||||
<Box>
|
||||
<Badge size="md" variant="solid">
|
||||
<Stack direction="row">
|
||||
<Text>chapters:</Text>
|
||||
<Text>{chaptersTotal}</Text>
|
||||
</Stack>
|
||||
</Badge>
|
||||
</Box>
|
||||
<Box>
|
||||
<Badge size="md" variant="solid">
|
||||
<Stack direction="row">
|
||||
<Text>words:</Text>
|
||||
<Text>{wordsTotal}</Text>
|
||||
</Stack>
|
||||
</Badge>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<Stack>
|
||||
<Text lineClamp={4}>{description}</Text>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Card.Body>
|
||||
</Card.Root>
|
||||
);
|
||||
}
|
||||
|
||||
export function IconBadge({
|
||||
children,
|
||||
iconClass,
|
||||
backgroundColor,
|
||||
size = 'lg'
|
||||
}: {
|
||||
children?: ReactNode;
|
||||
iconClass: string;
|
||||
backgroundColor?: BadgeProps['backgroundColor'];
|
||||
size?: 'sm' | 'md' | 'lg' | 'xs';
|
||||
}) {
|
||||
return (
|
||||
<Box flex={1} direction="row" justifyContent="center" alignItems="center">
|
||||
<Badge variant="solid" size={size} backgroundColor={backgroundColor}>
|
||||
<Stack direction="row">
|
||||
<Icon fontSize="xl">
|
||||
<i className={iconClass} />
|
||||
</Icon>
|
||||
{children}
|
||||
</Stack>
|
||||
</Badge>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
40
app/client/components/WorkingListSearch.tsx
Normal file
40
app/client/components/WorkingListSearch.tsx
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import { Button, Icon, Input, InputGroup, Stack } from '@chakra-ui/react';
|
||||
|
||||
export function WorkingListSearch({
|
||||
value,
|
||||
onChange,
|
||||
onSubmit
|
||||
}: {
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
onSubmit: (value: string) => void;
|
||||
}) {
|
||||
return (
|
||||
<form
|
||||
onSubmit={event => {
|
||||
event.preventDefault();
|
||||
onSubmit(value);
|
||||
}}
|
||||
>
|
||||
<Stack direction="row">
|
||||
<InputGroup
|
||||
flex="1"
|
||||
startElement={
|
||||
<Icon color="colorPalette.500">
|
||||
<i className="nf nf-oct-search" />
|
||||
</Icon>
|
||||
}
|
||||
>
|
||||
<Input
|
||||
value={value}
|
||||
onChange={event => onChange(event.currentTarget.value)}
|
||||
placeholder="Search works..."
|
||||
/>
|
||||
</InputGroup>
|
||||
<Button type="submit" border="none">
|
||||
Refresh
|
||||
</Button>
|
||||
</Stack>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
37
app/client/components/WorkingProgressStatusBadge.tsx
Normal file
37
app/client/components/WorkingProgressStatusBadge.tsx
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import { Badge, Box, Icon, Stack, Text } from '@chakra-ui/react';
|
||||
import { WorkingProgressStatus } from '@generated/types';
|
||||
import {
|
||||
assertUnreachable,
|
||||
toBgColorByProgressStatus,
|
||||
toWorkingProgressStatusLabel
|
||||
} from '../helpers';
|
||||
|
||||
export function WorkingProgressStatusBadge({
|
||||
progressStatus
|
||||
}: {
|
||||
progressStatus: WorkingProgressStatus;
|
||||
}) {
|
||||
return (
|
||||
<Box flex={1} justifyContent="center" alignItems="center">
|
||||
<Badge
|
||||
variant="solid"
|
||||
backgroundColor={toBgColorByProgressStatus(progressStatus)}
|
||||
size={'lg'}
|
||||
>
|
||||
<Stack direction="row">
|
||||
<Icon fontSize="xl">
|
||||
<i className={`${toWorkingProgressStatusIcon(progressStatus)}`} />
|
||||
</Icon>
|
||||
<Text>{toWorkingProgressStatusLabel(progressStatus)}</Text>
|
||||
</Stack>
|
||||
</Badge>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
function toWorkingProgressStatusIcon(value: WorkingProgressStatus): string {
|
||||
if (value === WorkingProgressStatus.InProgress) return 'nf nf-fa-clock';
|
||||
if (value === WorkingProgressStatus.Frozen) return 'nf nf-fa-snowflake';
|
||||
if (value === WorkingProgressStatus.Finished) return 'nf nf-fa-circle_check';
|
||||
assertUnreachable(value);
|
||||
}
|
||||
28
app/client/components/WorkingRatingBadge.tsx
Normal file
28
app/client/components/WorkingRatingBadge.tsx
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { BadgeProps, Text } from '@chakra-ui/react';
|
||||
import { IconBadge } from './WorkingListCard';
|
||||
|
||||
interface WorkingRatingParams {
|
||||
rating: string;
|
||||
color: BadgeProps['backgroundColor'];
|
||||
iconClass: string;
|
||||
}
|
||||
|
||||
export function WorkingRatingBadge({ ratingTotal }: { ratingTotal: number }) {
|
||||
const ratingParams: WorkingRatingParams =
|
||||
ratingTotal >= 0
|
||||
? {
|
||||
rating: ratingTotal.toString(),
|
||||
color: 'green.500',
|
||||
iconClass: 'nf nf-fa-angle_up'
|
||||
}
|
||||
: {
|
||||
rating: ratingTotal.toString().slice(1),
|
||||
color: 'red.500',
|
||||
iconClass: 'nf nf-fa-angle_down'
|
||||
};
|
||||
return (
|
||||
<IconBadge backgroundColor={ratingParams.color} iconClass={ratingParams.iconClass}>
|
||||
<Text>{ratingParams.rating}</Text>
|
||||
</IconBadge>
|
||||
);
|
||||
}
|
||||
|
|
@ -15,7 +15,6 @@ export function ColorModeProvider(props: ColorModeProviderProps) {
|
|||
|
||||
export function useColorMode() {
|
||||
const { resolvedTheme, setTheme } = useTheme();
|
||||
console.log(resolvedTheme);
|
||||
const toggleColorMode = () => {
|
||||
setTheme(resolvedTheme === 'light' ? 'dark' : 'light');
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
'use client';
|
||||
|
||||
import { ChakraProvider, defaultSystem, Theme } from '@chakra-ui/react';
|
||||
import { ChakraProvider, createSystem, defaultConfig, Theme } from '@chakra-ui/react';
|
||||
import { ColorModeProvider, type ColorModeProviderProps } from './color-mode';
|
||||
|
||||
export function Provider(props: ColorModeProviderProps) {
|
||||
const system = createSystem(defaultConfig, {
|
||||
theme: {
|
||||
tokens: {}
|
||||
}
|
||||
});
|
||||
return (
|
||||
<ChakraProvider value={defaultSystem}>
|
||||
<ChakraProvider value={system}>
|
||||
<Theme colorPalette="cyan">
|
||||
<ColorModeProvider defaultTheme="dark">{props.children}</ColorModeProvider>
|
||||
</Theme>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { gql } from '@apollo/client';
|
|||
|
||||
export const sessionFragment = gql`
|
||||
fragment Session on Session {
|
||||
userId
|
||||
accessToken
|
||||
}
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -1 +1,26 @@
|
|||
import { WorkingProgressStatus } from '@generated/types';
|
||||
|
||||
export function assertUnreachable(value: never): never {
|
||||
throw new Error(`Unhandled scenario: ${value}`);
|
||||
}
|
||||
|
||||
export function toBgColorByProgressStatus(value: WorkingProgressStatus): string {
|
||||
if (value === WorkingProgressStatus.InProgress) return 'yellow.500';
|
||||
if (value === WorkingProgressStatus.Frozen) return 'blue.500';
|
||||
if (value === WorkingProgressStatus.Finished) return 'green.500';
|
||||
assertUnreachable(value);
|
||||
}
|
||||
|
||||
export function toFgColorByProgressStatus(value: WorkingProgressStatus): string {
|
||||
if (value === WorkingProgressStatus.InProgress) return 'fg.warning';
|
||||
if (value === WorkingProgressStatus.Frozen) return 'fg.info';
|
||||
if (value === WorkingProgressStatus.Finished) return 'fg.success';
|
||||
assertUnreachable(value);
|
||||
}
|
||||
|
||||
export function toWorkingProgressStatusLabel(value: WorkingProgressStatus): string {
|
||||
if (value === WorkingProgressStatus.InProgress) return 'In progress';
|
||||
if (value === WorkingProgressStatus.Frozen) return 'Frozen';
|
||||
if (value === WorkingProgressStatus.Finished) return 'Finished';
|
||||
assertUnreachable(value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export function useAuth(): UseAuthOutput {
|
|||
successMsg: 'Logged out successfully.'
|
||||
});
|
||||
|
||||
if (!authContext) throw new Error('useAuth must be used within an AuthProvider');
|
||||
if (authContext == null) throw new Error('useAuth must be used within an AuthProvider');
|
||||
|
||||
return {
|
||||
...authContext,
|
||||
|
|
@ -45,7 +45,6 @@ export function useAuth(): UseAuthOutput {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (data != null) {
|
||||
authContext.setHeaders(data.login);
|
||||
return data.login;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,52 @@
|
|||
// interface UseIdentityProps {}
|
||||
import { ApolloError, ApolloQueryResult, gql, OperationVariables, useQuery } from '@apollo/client';
|
||||
import { Identity, IdentityRootQuery } from '@generated/types';
|
||||
import { createContext, useContext } from 'react';
|
||||
|
||||
// export function useIdentity(props: UseIdentityProps) {}
|
||||
export interface IdentityContext {
|
||||
data: Identity;
|
||||
refetch: () => void;
|
||||
}
|
||||
|
||||
export const IdentityContext = createContext<IdentityContext | null>(null);
|
||||
export const IdentityProvider = IdentityContext.Provider;
|
||||
|
||||
export function useIdentity(): IdentityContext | null {
|
||||
const identityContext = useContext(IdentityContext);
|
||||
if (identityContext == null) return null;
|
||||
return identityContext;
|
||||
}
|
||||
|
||||
export function useIdentityQuery({ skip }: { skip?: boolean }): {
|
||||
data: IdentityRootQuery | undefined;
|
||||
loading: boolean;
|
||||
error: ApolloError | undefined;
|
||||
refetch: (
|
||||
variables?: Partial<OperationVariables> | undefined
|
||||
) => Promise<ApolloQueryResult<IdentityRootQuery>>;
|
||||
} {
|
||||
const { data, loading, error, refetch } = useQuery<IdentityRootQuery>(query, {
|
||||
skip
|
||||
});
|
||||
return {
|
||||
data,
|
||||
loading,
|
||||
error,
|
||||
refetch
|
||||
};
|
||||
}
|
||||
|
||||
const query = gql`
|
||||
query IdentityRoot {
|
||||
identity {
|
||||
id
|
||||
email
|
||||
isDarkTheme
|
||||
user {
|
||||
id
|
||||
username
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
|
|
|||
40
app/client/hooks/usePaginatedQuery.tsx
Normal file
40
app/client/hooks/usePaginatedQuery.tsx
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import {
|
||||
ApolloError,
|
||||
ApolloQueryResult,
|
||||
MaybeMasked,
|
||||
OperationVariables,
|
||||
useQuery
|
||||
} from '@apollo/client';
|
||||
import { DocumentNode } from 'graphql';
|
||||
|
||||
interface UsePaginatedQueryProps {
|
||||
query: DocumentNode;
|
||||
input: {
|
||||
filter: {
|
||||
terms?: string | null;
|
||||
offset?: number | null;
|
||||
size?: number | null;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
interface UsePaginatedQueryReturn<T> {
|
||||
data?: MaybeMasked<T> | undefined;
|
||||
loading: boolean;
|
||||
error: ApolloError | undefined;
|
||||
refetch: (
|
||||
variables?: Partial<OperationVariables> | undefined
|
||||
) => Promise<ApolloQueryResult<MaybeMasked<T>>>;
|
||||
}
|
||||
|
||||
export function usePaginatedQuery<T>(props: UsePaginatedQueryProps): UsePaginatedQueryReturn<T> {
|
||||
const { data, loading, error, refetch } = useQuery<T>(props.query, {
|
||||
variables: { input: props.input }
|
||||
});
|
||||
return {
|
||||
data,
|
||||
loading,
|
||||
error,
|
||||
refetch
|
||||
};
|
||||
}
|
||||
33
app/client/hooks/useUserOneQuery.tsx
Normal file
33
app/client/hooks/useUserOneQuery.tsx
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import { ApolloError, ApolloQueryResult, gql, OperationVariables, useQuery } from '@apollo/client';
|
||||
import { UserOneQuery } from '@generated/types';
|
||||
|
||||
export function useUserOneQuery({ id, skip }: { id?: string; skip?: boolean }): {
|
||||
data: UserOneQuery | undefined;
|
||||
loading: boolean;
|
||||
error: ApolloError | undefined;
|
||||
refetch: (
|
||||
variables?: Partial<OperationVariables> | undefined
|
||||
) => Promise<ApolloQueryResult<UserOneQuery>>;
|
||||
} {
|
||||
const { data, loading, error, refetch } = useQuery<UserOneQuery>(query, {
|
||||
variables: { id },
|
||||
skip
|
||||
});
|
||||
return {
|
||||
data,
|
||||
loading,
|
||||
error,
|
||||
refetch
|
||||
};
|
||||
}
|
||||
|
||||
const query = gql`
|
||||
query UserOne($id: ID!) {
|
||||
userOne(id: $id) {
|
||||
id
|
||||
username
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { ApolloClient, ApolloProvider, HttpLink, InMemoryCache, from } from '@apollo/client';
|
||||
import { loadDevMessages, loadErrorMessages } from '@apollo/client/dev';
|
||||
import { onError } from '@apollo/client/link/error';
|
||||
import { Skeleton } from '@chakra-ui/react';
|
||||
import { Box, Center, Spinner } from '@chakra-ui/react';
|
||||
import '@client/assets/styles/index.css';
|
||||
import '@client/assets/styles/nerd-fonts-icons.css';
|
||||
import { Provider as ChakraProvider } from '@client/components/ui/provider';
|
||||
|
|
@ -10,6 +10,7 @@ import { RouterProvider, createRouter } from '@tanstack/react-router';
|
|||
import { StrictMode, useEffect, useState } from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import { AuthProvider, useRestAuth } from './hooks/auth';
|
||||
import { IdentityProvider, useIdentityQuery } from './hooks/identity';
|
||||
|
||||
// TanStackRouter - Import the generated route tree
|
||||
import { Session } from '@generated/types';
|
||||
|
|
@ -59,7 +60,11 @@ function App() {
|
|||
return (
|
||||
<StrictMode>
|
||||
<ChakraProvider>
|
||||
<Skeleton />
|
||||
<Box pos="absolute" inset="0">
|
||||
<Center h="full">
|
||||
<Spinner color="colorPalette.500" />
|
||||
</Center>
|
||||
</Box>
|
||||
</ChakraProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
|
|
@ -113,7 +118,7 @@ function App() {
|
|||
<ApolloProvider client={client}>
|
||||
<ChakraProvider>
|
||||
<Toaster />
|
||||
<RouterProvider router={router} context={{ isAuthenticated: authHeaders != null }} />
|
||||
<RouterProviderWrapper authHeaders={authHeaders} />
|
||||
</ChakraProvider>
|
||||
</ApolloProvider>
|
||||
</AuthProvider>
|
||||
|
|
@ -121,6 +126,28 @@ function App() {
|
|||
);
|
||||
}
|
||||
|
||||
function RouterProviderWrapper({ authHeaders }: { authHeaders: Session | null }) {
|
||||
const userId = authHeaders?.userId;
|
||||
const { data, loading, refetch } = useIdentityQuery({ skip: userId == null });
|
||||
|
||||
if (loading)
|
||||
return (
|
||||
<Box pos="absolute" inset="0">
|
||||
<Center h="full">
|
||||
<Spinner color="colorPalette.500" />
|
||||
</Center>
|
||||
</Box>
|
||||
);
|
||||
|
||||
return (
|
||||
<IdentityProvider
|
||||
value={userId != null && data != null ? { data: data.identity, refetch } : null}
|
||||
>
|
||||
<RouterProvider router={router} context={{ isAuthenticated: authHeaders != null }} />
|
||||
</IdentityProvider>
|
||||
);
|
||||
}
|
||||
|
||||
const rootElement = document.getElementById('root')!;
|
||||
if (!rootElement.innerHTML) {
|
||||
const root = ReactDOM.createRoot(rootElement);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
import { Separator, Icon, Menu, Stack, Text } from '@chakra-ui/react';
|
||||
import { Icon, Input, InputGroup, Kbd, Menu, Separator, Stack, Text } from '@chakra-ui/react';
|
||||
import { createRootRouteWithContext, Link, Outlet } from '@tanstack/react-router';
|
||||
import React from 'react';
|
||||
import { Avatar } from '../components/ui/avatar';
|
||||
import { Button } from '../components/ui/button';
|
||||
import { ColorModeButton } from '../components/ui/color-mode';
|
||||
import { Tooltip } from '../components/ui/tooltip';
|
||||
import { useAuth } from '../hooks/auth';
|
||||
import { useIdentity } from '../hooks/identity';
|
||||
import { appName } from '../main';
|
||||
import { ColorModeButton } from '../components/ui/color-mode';
|
||||
|
||||
const TanStackRouterDevtools =
|
||||
process.env.NODE_ENV === 'production'
|
||||
|
|
@ -26,37 +27,72 @@ interface RouterContext {
|
|||
|
||||
export const Route = createRootRouteWithContext<RouterContext>()({
|
||||
component: () => {
|
||||
const { isAuthenticated, logout } = useAuth();
|
||||
const { logout } = useAuth();
|
||||
const identity = useIdentity();
|
||||
|
||||
return (
|
||||
<Stack padding={3}>
|
||||
<Stack flexDirection="row" justifyContent="space-between" alignItems="center">
|
||||
<Stack flexDirection="row" alignItems="center" gap={4}>
|
||||
<Stack flexDirection="row" justifyContent="center" alignItems="center" gap={4}>
|
||||
<Link to="/">
|
||||
<Text color="colorPalette.500" fontSize="xl">
|
||||
[{appName}]
|
||||
</Text>
|
||||
</Link>
|
||||
<Link to="/about">
|
||||
<Icon color="colorPalette.500" fontSize="md">
|
||||
<i className="nf nf-oct-question" />
|
||||
<Stack direction="row" justifyContent="center" alignItems="center" gap={1}>
|
||||
<Icon fontSize={24} color="colorPalette.500">
|
||||
<i className="nf nf-md-bird" />
|
||||
</Icon>
|
||||
<Text fontSize="lg" fontWeight="bold">
|
||||
{appName}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Link>
|
||||
{/* <Stack hideBelow="md"> */}
|
||||
{/* <Link to="/about"> */}
|
||||
{/* <Icon color="colorPalette.500" fontSize="md"> */}
|
||||
{/* <i className="nf nf-oct-question" /> */}
|
||||
{/* </Icon> */}
|
||||
{/* </Link> */}
|
||||
{/* </Stack> */}
|
||||
</Stack>
|
||||
|
||||
<Stack flexDirection="row" alignItems="center" gap={4}>
|
||||
<InputGroup
|
||||
hideBelow="md"
|
||||
flex={1}
|
||||
alignItems="center"
|
||||
startElement={
|
||||
<Icon color="colorPalette.500">
|
||||
<i className="nf nf-oct-search" />
|
||||
</Icon>
|
||||
}
|
||||
endElement={<Kbd>⌘K</Kbd>}
|
||||
>
|
||||
<Input height={8} placeholder="Search works..." />
|
||||
</InputGroup>
|
||||
|
||||
<ColorModeButton />
|
||||
|
||||
{isAuthenticated ? (
|
||||
{identity != null ? (
|
||||
<Menu.Root>
|
||||
<Menu.Trigger>
|
||||
<Menu.Trigger css={{ '&:hover': { cursor: 'pointer' } }}>
|
||||
<Avatar
|
||||
// src={'https://avatars.githubusercontent.com/u/40203084?v=4'}
|
||||
fallback={'A'}
|
||||
size="sm"
|
||||
// src="https://avatars.githubusercontent.com/u/40203084?v=4"
|
||||
/>
|
||||
</Menu.Trigger>
|
||||
<Menu.Positioner mt={2}>
|
||||
<Menu.Content>
|
||||
<>
|
||||
<Menu.Content backgroundColor={'bg.subtle'}>
|
||||
<Link to={`/profile/${identity.data.user.username}`}>
|
||||
<Menu.Item value="/">
|
||||
<Tooltip content="My profile">
|
||||
<Stack direction="row">
|
||||
<Icon color="colorPalette.500" fontSize="xl">
|
||||
<i className="nf nf-fa-user" />
|
||||
</Icon>
|
||||
My profile
|
||||
</Stack>
|
||||
</Tooltip>
|
||||
</Menu.Item>
|
||||
</Link>
|
||||
|
||||
<Menu.Item value="logout" onClick={async () => logout()}>
|
||||
<Tooltip content="Log out">
|
||||
<Stack direction="row">
|
||||
|
|
@ -67,7 +103,6 @@ export const Route = createRootRouteWithContext<RouterContext>()({
|
|||
</Stack>
|
||||
</Tooltip>
|
||||
</Menu.Item>
|
||||
</>
|
||||
</Menu.Content>
|
||||
</Menu.Positioner>
|
||||
</Menu.Root>
|
||||
|
|
@ -75,30 +110,13 @@ export const Route = createRootRouteWithContext<RouterContext>()({
|
|||
<>
|
||||
<Separator orientation="vertical" height={5} />
|
||||
<Link to="/login">
|
||||
<Button>Sign in</Button>
|
||||
<Button height={8}>Sign in</Button>
|
||||
</Link>
|
||||
<Link to="/register">
|
||||
<Button>Sign up</Button>
|
||||
<Button height={8}>Sign up</Button>
|
||||
</Link>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* {!isAuthenticated ? (
|
||||
<>
|
||||
<Link to="/login">
|
||||
<Button>Sign in</Button>
|
||||
</Link>
|
||||
<Link to="/register">
|
||||
<Button>Sign up</Button>
|
||||
</Link>
|
||||
</>
|
||||
) : (
|
||||
<Tooltip content="Log out">
|
||||
<Icon color="colorPalette.500" fontSize="xl" onClick={async () => logout()}>
|
||||
<i className="nf nf-fa-sign_out" />
|
||||
</Icon>
|
||||
</Tooltip>
|
||||
)} */}
|
||||
</Stack>
|
||||
</Stack>
|
||||
<Separator style={{ padding: '4px' }} />
|
||||
|
|
|
|||
15
app/client/pages/editor.tsx
Normal file
15
app/client/pages/editor.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { Stack } from '@chakra-ui/react';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
import { Editor } from '../components/Editor';
|
||||
|
||||
export const Route = createFileRoute('/editor')({
|
||||
component: RouteComponent
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
return (
|
||||
<Stack justifyContent="center" alignItems="center">
|
||||
<Editor />
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
46
app/client/pages/example.tsx
Normal file
46
app/client/pages/example.tsx
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import { Box, Button, Stack, Text } from '@chakra-ui/react'
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
|
||||
import { gql, useQuery } from '@apollo/client'
|
||||
|
||||
import { BooksManyQuery } from '@generated/types'
|
||||
|
||||
export const Route = createFileRoute('/example')({
|
||||
component: Dashboard,
|
||||
})
|
||||
|
||||
function Dashboard() {
|
||||
const { data, refetch } = useQuery<BooksManyQuery>(getBooksQuery)
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<Text>Hello world!</Text>
|
||||
<Text>This is my template!</Text>
|
||||
<Stack>
|
||||
{data && (
|
||||
<>
|
||||
{data.booksMany.map((book: any) => (
|
||||
<Stack key={book.id}>
|
||||
<Text>{book.title}</Text>
|
||||
<Text>{book.author}</Text>
|
||||
</Stack>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
<Box>
|
||||
<Button onClick={async () => refetch()}>Refetch</Button>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
|
||||
const getBooksQuery = gql`
|
||||
query BooksMany {
|
||||
booksMany {
|
||||
id
|
||||
author
|
||||
title
|
||||
}
|
||||
}
|
||||
`
|
||||
|
|
@ -1,46 +1,139 @@
|
|||
import { Box, Button, Stack, Text } from '@chakra-ui/react';
|
||||
import { gql } from '@apollo/client';
|
||||
import { Skeleton, Stack } from '@chakra-ui/react';
|
||||
import { WorkingListQuery } from '@generated/types';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
|
||||
import { BooksManyQuery } from '@generated/types';
|
||||
import { useState } from 'react';
|
||||
import { Pagination } from '../components/Pagination';
|
||||
import { WorkingList } from '../components/WorkingList';
|
||||
import { WorkingListSearch } from '../components/WorkingListSearch';
|
||||
import { usePaginatedQuery } from '../hooks/usePaginatedQuery';
|
||||
|
||||
export const Route = createFileRoute('/')({
|
||||
component: Dashboard
|
||||
component: RouteComponent
|
||||
});
|
||||
|
||||
function Dashboard() {
|
||||
const { data, refetch } = useQuery<BooksManyQuery>(getBooksQuery);
|
||||
function RouteComponent() {
|
||||
const [workingSearchValue, setWorkingSearchValue] = useState<string>('');
|
||||
const [workingsListPage, setWorkingsListPage] = useState<number>(1);
|
||||
const [workingsListPageSize, setWorkingsListPageSize] = useState<number>(2);
|
||||
const startIndex = (workingsListPage - 1) * workingsListPageSize;
|
||||
|
||||
const { data } = usePaginatedQuery<WorkingListQuery>({
|
||||
query,
|
||||
input: {
|
||||
filter: {
|
||||
terms: workingSearchValue,
|
||||
offset: startIndex,
|
||||
size: workingsListPageSize
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<Text>Hello world!</Text>
|
||||
<Text>This is my template!</Text>
|
||||
<Stack>
|
||||
{data && (
|
||||
<Stack justifyContent="center" alignItems="center">
|
||||
<Stack width="90%">
|
||||
<WorkingListSearch
|
||||
value={workingSearchValue}
|
||||
onSubmit={value => {
|
||||
alert(value);
|
||||
}}
|
||||
onChange={value => setWorkingSearchValue(value)}
|
||||
/>
|
||||
|
||||
{data != null ? (
|
||||
<>
|
||||
{data.booksMany.map((book: any) => (
|
||||
<Stack key={book.id}>
|
||||
<Text>{book.title}</Text>
|
||||
<Text>{book.author}</Text>
|
||||
</Stack>
|
||||
))}
|
||||
<WorkingList
|
||||
workingsList={data.workingMany.items.map(item => ({
|
||||
...item,
|
||||
chaptersTotal: item.chapters.total,
|
||||
reviewsTotal: item.reviews.total
|
||||
}))}
|
||||
/>
|
||||
|
||||
<Pagination
|
||||
total={data.workingMany.total}
|
||||
page={workingsListPage}
|
||||
setPage={setWorkingsListPage}
|
||||
pageSize={workingsListPageSize}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
<Box>
|
||||
<Button onClick={async () => refetch()}>Refetch</Button>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
const getBooksQuery = gql`
|
||||
query BooksMany {
|
||||
booksMany {
|
||||
const query = gql`
|
||||
query WorkingList($input: WorkingManyInput!) {
|
||||
workingMany(input: $input) {
|
||||
items {
|
||||
id
|
||||
author
|
||||
title
|
||||
description
|
||||
author {
|
||||
id
|
||||
username
|
||||
}
|
||||
progressStatus
|
||||
updatedAt
|
||||
chapters {
|
||||
total
|
||||
}
|
||||
wordsTotal
|
||||
ratingTotal
|
||||
reviews {
|
||||
total
|
||||
}
|
||||
}
|
||||
total
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
// const workingData1: WorkingCardProps = {
|
||||
// id: '1',
|
||||
// title: 'Worth the Candle',
|
||||
// description: `A teenager struggling after the death of his best friend finds himself in a fantasy
|
||||
// world - one which seems to be an amalgamation of every Dungeons and Dragons campaign
|
||||
// they ever played together. Now he's stuck trying to find the answers to why he's there
|
||||
// and what this world is trying to say. The most terrifying answer might be that this
|
||||
// world is an expression of the person he was back on Earth.`,
|
||||
// author: {
|
||||
// id: '1',
|
||||
// createdAt: '12.8.2025',
|
||||
// updatedAt: '4.9.2025',
|
||||
// username: 'AlexanderWhales'
|
||||
// },
|
||||
// progressStatus: WorkingProgressStatus.Finished,
|
||||
// updatedAt: '20.10.2025',
|
||||
// chaptersTotal: 10,
|
||||
// wordsTotal: 34000,
|
||||
// ratingTotal: 10,
|
||||
// reviewsTotal: 3
|
||||
// };
|
||||
//
|
||||
// const workingData2: WorkingCardProps = {
|
||||
// id: '2',
|
||||
// title: 'Test',
|
||||
// description: `Description.`,
|
||||
// author: {
|
||||
// id: '1',
|
||||
// createdAt: '12.8.2025',
|
||||
// updatedAt: '4.9.2025',
|
||||
// username: 'JohnSmith'
|
||||
// },
|
||||
// progressStatus: WorkingProgressStatus.InProgress,
|
||||
// updatedAt: '20.10.2025',
|
||||
// chaptersTotal: 10,
|
||||
// wordsTotal: 1200,
|
||||
// ratingTotal: -10,
|
||||
// reviewsTotal: 0
|
||||
// };
|
||||
//
|
||||
// const mockWorkingData = {
|
||||
// total: 4,
|
||||
// items: [workingData1, workingData2, { ...workingData1, id: '3' }, { ...workingData2, id: '4' }]
|
||||
// };
|
||||
//
|
||||
|
|
|
|||
10
app/client/pages/profile/$username.tsx
Normal file
10
app/client/pages/profile/$username.tsx
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { createFileRoute } from '@tanstack/react-router';
|
||||
|
||||
export const Route = createFileRoute('/profile/$username')({
|
||||
component: RouteComponent
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
const { username } = Route.useParams();
|
||||
return <div>{`Hello, "${username}"!`}</div>;
|
||||
}
|
||||
|
|
@ -15,8 +15,11 @@ import { createFileRoute } from '@tanstack/react-router'
|
|||
import { Route as rootRoute } from './pages/__root'
|
||||
import { Route as RegisterImport } from './pages/register'
|
||||
import { Route as LoginImport } from './pages/login'
|
||||
import { Route as ExampleImport } from './pages/example'
|
||||
import { Route as EditorImport } from './pages/editor'
|
||||
import { Route as AboutImport } from './pages/about'
|
||||
import { Route as IndexImport } from './pages/index'
|
||||
import { Route as ProfileUsernameImport } from './pages/profile/$username'
|
||||
|
||||
// Create Virtual Routes
|
||||
|
||||
|
|
@ -42,6 +45,18 @@ const LoginRoute = LoginImport.update({
|
|||
getParentRoute: () => rootRoute,
|
||||
} as any)
|
||||
|
||||
const ExampleRoute = ExampleImport.update({
|
||||
id: '/example',
|
||||
path: '/example',
|
||||
getParentRoute: () => rootRoute,
|
||||
} as any)
|
||||
|
||||
const EditorRoute = EditorImport.update({
|
||||
id: '/editor',
|
||||
path: '/editor',
|
||||
getParentRoute: () => rootRoute,
|
||||
} as any)
|
||||
|
||||
const AboutRoute = AboutImport.update({
|
||||
id: '/about',
|
||||
path: '/about',
|
||||
|
|
@ -54,6 +69,12 @@ const IndexRoute = IndexImport.update({
|
|||
getParentRoute: () => rootRoute,
|
||||
} as any)
|
||||
|
||||
const ProfileUsernameRoute = ProfileUsernameImport.update({
|
||||
id: '/profile/$username',
|
||||
path: '/profile/$username',
|
||||
getParentRoute: () => rootRoute,
|
||||
} as any)
|
||||
|
||||
// Populate the FileRoutesByPath interface
|
||||
|
||||
declare module '@tanstack/react-router' {
|
||||
|
|
@ -72,6 +93,20 @@ declare module '@tanstack/react-router' {
|
|||
preLoaderRoute: typeof AboutImport
|
||||
parentRoute: typeof rootRoute
|
||||
}
|
||||
'/editor': {
|
||||
id: '/editor'
|
||||
path: '/editor'
|
||||
fullPath: '/editor'
|
||||
preLoaderRoute: typeof EditorImport
|
||||
parentRoute: typeof rootRoute
|
||||
}
|
||||
'/example': {
|
||||
id: '/example'
|
||||
path: '/example'
|
||||
fullPath: '/example'
|
||||
preLoaderRoute: typeof ExampleImport
|
||||
parentRoute: typeof rootRoute
|
||||
}
|
||||
'/login': {
|
||||
id: '/login'
|
||||
path: '/login'
|
||||
|
|
@ -93,6 +128,13 @@ declare module '@tanstack/react-router' {
|
|||
preLoaderRoute: typeof BookLazyImport
|
||||
parentRoute: typeof rootRoute
|
||||
}
|
||||
'/profile/$username': {
|
||||
id: '/profile/$username'
|
||||
path: '/profile/$username'
|
||||
fullPath: '/profile/$username'
|
||||
preLoaderRoute: typeof ProfileUsernameImport
|
||||
parentRoute: typeof rootRoute
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -101,51 +143,91 @@ declare module '@tanstack/react-router' {
|
|||
export interface FileRoutesByFullPath {
|
||||
'/': typeof IndexRoute
|
||||
'/about': typeof AboutRoute
|
||||
'/editor': typeof EditorRoute
|
||||
'/example': typeof ExampleRoute
|
||||
'/login': typeof LoginRoute
|
||||
'/register': typeof RegisterRoute
|
||||
'/book': typeof BookLazyRoute
|
||||
'/profile/$username': typeof ProfileUsernameRoute
|
||||
}
|
||||
|
||||
export interface FileRoutesByTo {
|
||||
'/': typeof IndexRoute
|
||||
'/about': typeof AboutRoute
|
||||
'/editor': typeof EditorRoute
|
||||
'/example': typeof ExampleRoute
|
||||
'/login': typeof LoginRoute
|
||||
'/register': typeof RegisterRoute
|
||||
'/book': typeof BookLazyRoute
|
||||
'/profile/$username': typeof ProfileUsernameRoute
|
||||
}
|
||||
|
||||
export interface FileRoutesById {
|
||||
__root__: typeof rootRoute
|
||||
'/': typeof IndexRoute
|
||||
'/about': typeof AboutRoute
|
||||
'/editor': typeof EditorRoute
|
||||
'/example': typeof ExampleRoute
|
||||
'/login': typeof LoginRoute
|
||||
'/register': typeof RegisterRoute
|
||||
'/book': typeof BookLazyRoute
|
||||
'/profile/$username': typeof ProfileUsernameRoute
|
||||
}
|
||||
|
||||
export interface FileRouteTypes {
|
||||
fileRoutesByFullPath: FileRoutesByFullPath
|
||||
fullPaths: '/' | '/about' | '/login' | '/register' | '/book'
|
||||
fullPaths:
|
||||
| '/'
|
||||
| '/about'
|
||||
| '/editor'
|
||||
| '/example'
|
||||
| '/login'
|
||||
| '/register'
|
||||
| '/book'
|
||||
| '/profile/$username'
|
||||
fileRoutesByTo: FileRoutesByTo
|
||||
to: '/' | '/about' | '/login' | '/register' | '/book'
|
||||
id: '__root__' | '/' | '/about' | '/login' | '/register' | '/book'
|
||||
to:
|
||||
| '/'
|
||||
| '/about'
|
||||
| '/editor'
|
||||
| '/example'
|
||||
| '/login'
|
||||
| '/register'
|
||||
| '/book'
|
||||
| '/profile/$username'
|
||||
id:
|
||||
| '__root__'
|
||||
| '/'
|
||||
| '/about'
|
||||
| '/editor'
|
||||
| '/example'
|
||||
| '/login'
|
||||
| '/register'
|
||||
| '/book'
|
||||
| '/profile/$username'
|
||||
fileRoutesById: FileRoutesById
|
||||
}
|
||||
|
||||
export interface RootRouteChildren {
|
||||
IndexRoute: typeof IndexRoute
|
||||
AboutRoute: typeof AboutRoute
|
||||
EditorRoute: typeof EditorRoute
|
||||
ExampleRoute: typeof ExampleRoute
|
||||
LoginRoute: typeof LoginRoute
|
||||
RegisterRoute: typeof RegisterRoute
|
||||
BookLazyRoute: typeof BookLazyRoute
|
||||
ProfileUsernameRoute: typeof ProfileUsernameRoute
|
||||
}
|
||||
|
||||
const rootRouteChildren: RootRouteChildren = {
|
||||
IndexRoute: IndexRoute,
|
||||
AboutRoute: AboutRoute,
|
||||
EditorRoute: EditorRoute,
|
||||
ExampleRoute: ExampleRoute,
|
||||
LoginRoute: LoginRoute,
|
||||
RegisterRoute: RegisterRoute,
|
||||
BookLazyRoute: BookLazyRoute,
|
||||
ProfileUsernameRoute: ProfileUsernameRoute,
|
||||
}
|
||||
|
||||
export const routeTree = rootRoute
|
||||
|
|
@ -160,9 +242,12 @@ export const routeTree = rootRoute
|
|||
"children": [
|
||||
"/",
|
||||
"/about",
|
||||
"/editor",
|
||||
"/example",
|
||||
"/login",
|
||||
"/register",
|
||||
"/book"
|
||||
"/book",
|
||||
"/profile/$username"
|
||||
]
|
||||
},
|
||||
"/": {
|
||||
|
|
@ -171,6 +256,12 @@ export const routeTree = rootRoute
|
|||
"/about": {
|
||||
"filePath": "about.tsx"
|
||||
},
|
||||
"/editor": {
|
||||
"filePath": "editor.tsx"
|
||||
},
|
||||
"/example": {
|
||||
"filePath": "example.tsx"
|
||||
},
|
||||
"/login": {
|
||||
"filePath": "login.tsx"
|
||||
},
|
||||
|
|
@ -179,6 +270,9 @@ export const routeTree = rootRoute
|
|||
},
|
||||
"/book": {
|
||||
"filePath": "book.lazy.tsx"
|
||||
},
|
||||
"/profile/$username": {
|
||||
"filePath": "profile/$username.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
3
app/common.ts
Normal file
3
app/common.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export function call<T>(fn: () => T) {
|
||||
return fn();
|
||||
}
|
||||
|
|
@ -43,7 +43,7 @@ export async function refreshTokenController(req: Request, res: Response) {
|
|||
expiresIn: config.accessToken.expiresIn
|
||||
});
|
||||
|
||||
const session: Session = { accessToken };
|
||||
const session: Session = { userId: user.id, accessToken };
|
||||
res.json(session);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
|
|
|||
|
|
@ -2,17 +2,21 @@
|
|||
import { MutationResolvers, QueryResolvers } from '@generated/types';
|
||||
|
||||
/* Query */
|
||||
import { BooksManyResolver } from './resolvers/booksManyResolver';
|
||||
import { BookOneResolver } from './resolvers/bookOneResolver';
|
||||
import { BooksManyResolver } from './resolvers/booksManyResolver';
|
||||
import { IdentityResolver } from './resolvers/identityResolver';
|
||||
import { UserOneResolver } from './resolvers/userOneResolver';
|
||||
|
||||
/* Mutation */
|
||||
import { SignUpResolver } from './resolvers/auth/signUp';
|
||||
import { LoginResolver } from './resolvers/auth/login';
|
||||
import { LogoutResolver } from './resolvers/auth/logout';
|
||||
import { SignUpResolver } from './resolvers/auth/signUp';
|
||||
|
||||
export const Query: QueryResolvers = {
|
||||
booksMany: BooksManyResolver,
|
||||
bookOne: BookOneResolver
|
||||
bookOne: BookOneResolver,
|
||||
identity: IdentityResolver,
|
||||
userOne: UserOneResolver
|
||||
};
|
||||
|
||||
export const Mutation: MutationResolvers = {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ export async function LoginResolver(
|
|||
});
|
||||
|
||||
return {
|
||||
userId: user.id,
|
||||
accessToken
|
||||
};
|
||||
}
|
||||
|
|
|
|||
14
app/server/graphql/resolvers/identityResolver.ts
Normal file
14
app/server/graphql/resolvers/identityResolver.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { IdentityContext } from '@app/server/identity';
|
||||
import { prisma } from '@app/server/prisma/client';
|
||||
import { Identity } from '@generated/types';
|
||||
import { toIdentitySchema } from './mappers/identityMapper';
|
||||
|
||||
export async function IdentityResolver(
|
||||
_: any,
|
||||
__: any,
|
||||
{ identity }: IdentityContext
|
||||
): Promise<Identity> {
|
||||
if (identity == null) throw new Error('Unauthorized.');
|
||||
const model = await prisma.user.findUniqueOrThrow({ where: { id: identity.id } });
|
||||
return toIdentitySchema(model);
|
||||
}
|
||||
12
app/server/graphql/resolvers/mappers/identityMapper.ts
Normal file
12
app/server/graphql/resolvers/mappers/identityMapper.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import { Identity as IdentitySchema } from '@generated/types';
|
||||
import { User } from '@prisma/client';
|
||||
import { toUserSchema } from './userMapper';
|
||||
|
||||
export async function toIdentitySchema(model: User): Promise<IdentitySchema> {
|
||||
return {
|
||||
id: model.id,
|
||||
email: model.email,
|
||||
isDarkTheme: true,
|
||||
user: await toUserSchema(model)
|
||||
};
|
||||
}
|
||||
11
app/server/graphql/resolvers/mappers/userMapper.ts
Normal file
11
app/server/graphql/resolvers/mappers/userMapper.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { User as UserSchema } from '@generated/types';
|
||||
import { User } from '@prisma/client';
|
||||
|
||||
export async function toUserSchema(model: User): Promise<UserSchema> {
|
||||
return {
|
||||
id: model.id,
|
||||
username: model.username,
|
||||
createdAt: model.createdAt.toISOString(),
|
||||
updatedAt: model.updatedAt.toISOString()
|
||||
};
|
||||
}
|
||||
13
app/server/graphql/resolvers/userOneResolver.ts
Normal file
13
app/server/graphql/resolvers/userOneResolver.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { IdentityContext } from '@app/server/identity';
|
||||
import { prisma } from '@app/server/prisma/client';
|
||||
import { QueryUserOneArgs, User } from '@generated/types';
|
||||
import { toUserSchema } from './mappers/userMapper';
|
||||
|
||||
export async function UserOneResolver(
|
||||
_: any,
|
||||
{ id }: QueryUserOneArgs,
|
||||
{ identity }: IdentityContext
|
||||
): Promise<User> {
|
||||
const model = await prisma.user.findUniqueOrThrow({ where: { id } });
|
||||
return toUserSchema(model);
|
||||
}
|
||||
|
|
@ -3,6 +3,9 @@ scalar Void
|
|||
type Query {
|
||||
booksMany: [Book!]!
|
||||
bookOne(id: ID!): Book!
|
||||
identity: Identity!
|
||||
userOne(id: ID!): User!
|
||||
workingMany(input: WorkingManyInput!): WorkingManyOutput!
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
|
|
@ -23,11 +26,89 @@ input LoginInput {
|
|||
}
|
||||
|
||||
type Session {
|
||||
userId: ID!
|
||||
accessToken: String!
|
||||
}
|
||||
|
||||
type Identity {
|
||||
id: ID!
|
||||
email: String!
|
||||
isDarkTheme: Boolean!
|
||||
user: User!
|
||||
}
|
||||
|
||||
type User {
|
||||
id: ID!
|
||||
username: String!
|
||||
createdAt: String!
|
||||
updatedAt: String!
|
||||
}
|
||||
|
||||
type Book {
|
||||
id: ID!
|
||||
title: String!
|
||||
author: String!
|
||||
}
|
||||
|
||||
input Working
|
||||
|
||||
input PaginationFilterInput {
|
||||
terms: String
|
||||
offset: Int
|
||||
size: Int
|
||||
}
|
||||
|
||||
input WorkingManyInput {
|
||||
filter: PaginationFilterInput!
|
||||
}
|
||||
|
||||
enum WorkingProgressStatus {
|
||||
inProgress
|
||||
frozen
|
||||
finished
|
||||
}
|
||||
|
||||
type WorkingManyOutput {
|
||||
items: [Working!]!
|
||||
total: Int!
|
||||
}
|
||||
|
||||
type Working {
|
||||
id: ID!
|
||||
title: String!
|
||||
description: String!
|
||||
author: User!
|
||||
createdAt: String!
|
||||
updatedAt: String!
|
||||
progressStatus: WorkingProgressStatus!
|
||||
wordsTotal: Int!
|
||||
ratingTotal: Int!
|
||||
chapters: ChapterManyOutput!
|
||||
reviews: ReviewManyOutput!
|
||||
}
|
||||
|
||||
type ChapterManyOutput {
|
||||
items: [Chapter!]!
|
||||
total: Int!
|
||||
}
|
||||
|
||||
type Chapter {
|
||||
id: ID!
|
||||
title: String!
|
||||
createdAt: String!
|
||||
updatedAt: String!
|
||||
foreword: String!
|
||||
footnote: String!
|
||||
}
|
||||
|
||||
type ReviewManyOutput {
|
||||
items: [Review!]!
|
||||
total: Int!
|
||||
}
|
||||
|
||||
type Review {
|
||||
id: ID!
|
||||
author: User!
|
||||
text: String!
|
||||
ratingTotal: Int!
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
import { Session } from '@generated/types';
|
||||
import 'dotenv/config';
|
||||
import { Request, Response } from 'express';
|
||||
import { GraphQLError } from 'graphql';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { config } from './main';
|
||||
import { prisma } from './prisma/client';
|
||||
import { GraphQLError } from 'graphql';
|
||||
|
||||
export interface IdentityContext {
|
||||
req: Request;
|
||||
res: Response;
|
||||
identity?: {
|
||||
id: string;
|
||||
email: string;
|
||||
username: string;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,12 +10,14 @@ datasource db {
|
|||
model User {
|
||||
id String @id
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
email String @unique @db.VarChar(255)
|
||||
username String @unique @db.VarChar(255)
|
||||
password String
|
||||
|
||||
refreshToken String? @unique @db.VarChar(255)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
isDarkMode Boolean @default(true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/ln-logo.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>ln</title>
|
||||
<title>echoes</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
|
|
|||
476
package-lock.json
generated
476
package-lock.json
generated
|
|
@ -12,13 +12,18 @@
|
|||
"@apollo/server": "^4.11.2",
|
||||
"@chakra-ui/react": "^3.15.0",
|
||||
"@chakra-ui/toast": "^7.0.2",
|
||||
"@coolbytes/editorjs-link": "^1.0.0",
|
||||
"@deftomat/opinionated": "^1.1.3",
|
||||
"@editorjs/editorjs": "^2.30.8",
|
||||
"@editorjs/header": "^2.8.8",
|
||||
"@editorjs/link": "^2.6.2",
|
||||
"@editorjs/list": "^2.0.8",
|
||||
"@editorjs/quote": "^2.7.6",
|
||||
"@emotion/react": "^11.13.5",
|
||||
"@hookform/resolvers": "^3.9.1",
|
||||
"@prisma/client": "^6.4.1",
|
||||
"@tanstack/react-router": "^1.85.0",
|
||||
"@tanstack/router-vite-plugin": "^1.84.4",
|
||||
"@types/cors": "^2.8.17",
|
||||
"apollo-link-logger": "^2.0.1",
|
||||
"bcrypt": "^5.1.1",
|
||||
"cookie-parser": "^1.4.7",
|
||||
|
|
@ -49,6 +54,7 @@
|
|||
"@tanstack/router-plugin": "^1.84.4",
|
||||
"@types/bcrypt": "^5.0.2",
|
||||
"@types/cookie-parser": "^1.4.8",
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/jsonwebtoken": "^9.0.9",
|
||||
"@types/node": "^20.9.3",
|
||||
|
|
@ -1807,6 +1813,18 @@
|
|||
"sisteransi": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@codexteam/icons": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@codexteam/icons/-/icons-0.0.5.tgz",
|
||||
"integrity": "sha512-s6H2KXhLz2rgbMZSkRm8dsMJvyUNZsEjxobBEg9ztdrb1B2H3pEzY6iTwI4XUPJWJ3c3qRKwV4TrO3J5jUdoQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@coolbytes/editorjs-link": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@coolbytes/editorjs-link/-/editorjs-link-1.0.0.tgz",
|
||||
"integrity": "sha512-OiZL+l2TC+Urt9jn6hULG/yUMfB1F+M4GUoZv8naCinLs4frB50QpkWp8oNOuiJUBZW4la5uquQQpcYYxfd/Eg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@deftomat/opinionated": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@deftomat/opinionated/-/opinionated-1.1.3.tgz",
|
||||
|
|
@ -1894,9 +1912,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@deftomat/opinionated/node_modules/glob": {
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz",
|
||||
"integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==",
|
||||
"version": "11.0.2",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.2.tgz",
|
||||
"integrity": "sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
|
|
@ -2257,6 +2275,84 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@editorjs/dom": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@editorjs/dom/-/dom-0.0.5.tgz",
|
||||
"integrity": "sha512-SZ78Gwpkp3EUhjBIp0lSojeQ35V9acF8SubJsMeOH/vlOUE40GOnvvwWZnF05lO7bIB0dOHhhJy4N7IIAWxP2w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@editorjs/helpers": "^0.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@editorjs/editorjs": {
|
||||
"version": "2.30.8",
|
||||
"resolved": "https://registry.npmjs.org/@editorjs/editorjs/-/editorjs-2.30.8.tgz",
|
||||
"integrity": "sha512-ClFuxI1qZTfXPJTacQfsJtOUP6bKoIe6BQNdAvGsDTDVwMnZEzoaSOwvUpdZEE56xppVfQueNK/1MElV9SJKHg==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@editorjs/header": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/@editorjs/header/-/header-2.8.8.tgz",
|
||||
"integrity": "sha512-bsMSs34u2hoi0UBuRoc5EGWXIFzJiwYgkFUYQGVm63y5FU+s8zPBmVx5Ip2sw1xgs0fqfDROqmteMvvmbCy62w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@codexteam/icons": "^0.0.5",
|
||||
"@editorjs/editorjs": "^2.29.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@editorjs/helpers": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@editorjs/helpers/-/helpers-0.0.4.tgz",
|
||||
"integrity": "sha512-ieg3dzo2m1/ELze/RMNADiAiC5amXxIlVXoJ5vvXITOu/p/dPsrF+Oi3h5gBYvtGk9vg5LJUSG5YWU0tBUO1tw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@editorjs/link": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@editorjs/link/-/link-2.6.2.tgz",
|
||||
"integrity": "sha512-3cPx6M4ZvwDDvsi0E0fvMR3rvveAV/C0GRo1JLeZJ9cG9QgyoNolj4eu5Eqx3/r1XTC/he54qYEIZ/Dc4Lr4Ow==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.10.2",
|
||||
"@codexteam/icons": "^0.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@editorjs/link/node_modules/@codexteam/icons": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@codexteam/icons/-/icons-0.0.4.tgz",
|
||||
"integrity": "sha512-V8N/TY2TGyas4wLrPIFq7bcow68b3gu8DfDt1+rrHPtXxcexadKauRJL6eQgfG7Z0LCrN4boLRawR4S9gjIh/Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@editorjs/list": {
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@editorjs/list/-/list-2.0.8.tgz",
|
||||
"integrity": "sha512-/EJNvpeJYa1YDtYa85ug9R3sbDyI5ZlMHQ2bIh5S9iPa19qXe45jk6kgcew+jMNQq3j4NS4Q6YeeFbU1QkNMWw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@codexteam/icons": "^0.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@editorjs/list/node_modules/@codexteam/icons": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@codexteam/icons/-/icons-0.3.3.tgz",
|
||||
"integrity": "sha512-cp7mkZPgmBuSxigTm3Vb+DtVHYeX7qXfQd7o05vcLD8Ag5WvRlol2QSn5P10k0CDAJwmkH9nQGQLBycErS9lsQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@editorjs/quote": {
|
||||
"version": "2.7.6",
|
||||
"resolved": "https://registry.npmjs.org/@editorjs/quote/-/quote-2.7.6.tgz",
|
||||
"integrity": "sha512-D01KUMSDj2r+6Z+xjDkQqI+y6URpeHCvj0+P4pah+GtkG040lWjFb2H4pgHFXuol2cbfyAoraYSw85fuPheCvw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@codexteam/icons": "^0.3.2",
|
||||
"@editorjs/dom": "^0.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@editorjs/quote/node_modules/@codexteam/icons": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@codexteam/icons/-/icons-0.3.3.tgz",
|
||||
"integrity": "sha512-cp7mkZPgmBuSxigTm3Vb+DtVHYeX7qXfQd7o05vcLD8Ag5WvRlol2QSn5P10k0CDAJwmkH9nQGQLBycErS9lsQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@emotion/babel-plugin": {
|
||||
"version": "11.13.5",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz",
|
||||
|
|
@ -2411,9 +2507,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz",
|
||||
"integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz",
|
||||
"integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
|
|
@ -2427,9 +2523,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz",
|
||||
"integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz",
|
||||
"integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
|
@ -2443,9 +2539,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz",
|
||||
"integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz",
|
||||
"integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -2459,9 +2555,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz",
|
||||
"integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz",
|
||||
"integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -2475,9 +2571,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz",
|
||||
"integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz",
|
||||
"integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -2491,9 +2587,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz",
|
||||
"integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz",
|
||||
"integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -2507,9 +2603,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz",
|
||||
"integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz",
|
||||
"integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -2523,9 +2619,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz",
|
||||
"integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz",
|
||||
"integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -2539,9 +2635,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz",
|
||||
"integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz",
|
||||
"integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
|
@ -2555,9 +2651,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz",
|
||||
"integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz",
|
||||
"integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -2571,9 +2667,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz",
|
||||
"integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz",
|
||||
"integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
|
|
@ -2587,9 +2683,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz",
|
||||
"integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz",
|
||||
"integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
|
|
@ -2603,9 +2699,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz",
|
||||
"integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz",
|
||||
"integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
|
|
@ -2619,9 +2715,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz",
|
||||
"integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz",
|
||||
"integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
|
|
@ -2635,9 +2731,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz",
|
||||
"integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz",
|
||||
"integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
|
|
@ -2651,9 +2747,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz",
|
||||
"integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz",
|
||||
"integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
|
|
@ -2667,9 +2763,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz",
|
||||
"integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz",
|
||||
"integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -2683,9 +2779,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-arm64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz",
|
||||
"integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz",
|
||||
"integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -2699,9 +2795,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz",
|
||||
"integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz",
|
||||
"integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -2715,9 +2811,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-arm64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz",
|
||||
"integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz",
|
||||
"integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -2731,9 +2827,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz",
|
||||
"integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz",
|
||||
"integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -2747,9 +2843,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz",
|
||||
"integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz",
|
||||
"integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -2763,9 +2859,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz",
|
||||
"integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz",
|
||||
"integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -2779,9 +2875,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz",
|
||||
"integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz",
|
||||
"integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
|
|
@ -2795,9 +2891,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz",
|
||||
"integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz",
|
||||
"integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -2896,6 +2992,13 @@
|
|||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@fastify/busboy": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.1.1.tgz",
|
||||
"integrity": "sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@floating-ui/core": {
|
||||
"version": "1.6.9",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz",
|
||||
|
|
@ -3052,16 +3155,16 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@graphql-codegen/cli/node_modules/yaml": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz",
|
||||
"integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==",
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz",
|
||||
"integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"yaml": "bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
"node": ">= 14.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@graphql-codegen/client-preset": {
|
||||
|
|
@ -3604,13 +3707,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/fetch": {
|
||||
"version": "0.10.5",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.10.5.tgz",
|
||||
"integrity": "sha512-+yFJU3hmXPAHJULwx0VzCIsvr/H0lvbPvbOH3areOH3NAuCxCwaJsQ8w6/MwwMcvEWIynSsmAxoyaH04KeosPg==",
|
||||
"version": "0.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.10.7.tgz",
|
||||
"integrity": "sha512-sL31zX8BqZovZc38ovBFmKEfao9AzZ/24sWSHKNhDhcnzIO/PYAX2xF6vYtgU9hinrEGlvScTTyKSMynHGdfEA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@whatwg-node/node-fetch": "^0.7.11",
|
||||
"@whatwg-node/node-fetch": "^0.7.19",
|
||||
"urlpattern-polyfill": "^10.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -3618,15 +3721,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/node-fetch": {
|
||||
"version": "0.7.17",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.7.17.tgz",
|
||||
"integrity": "sha512-Ni8A2H/r6brNf4u8Y7ATxmWUD0xltsQ6a4NnjWSbw4PgaT34CbY+u4QtVsFj9pTC3dBKJADKjac3AieAig+PZA==",
|
||||
"version": "0.7.20",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.7.20.tgz",
|
||||
"integrity": "sha512-2LI5HkZcdAODb6umb7MUxkWYNUi3j6apgQvIzp+X3w3AVPdvVsshvjaMo4gwLeFtfs+cyMNOLTm9Hhm/TXq6DA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^3.1.1",
|
||||
"@whatwg-node/disposablestack": "^0.0.6",
|
||||
"@whatwg-node/promise-helpers": "^1.2.5",
|
||||
"busboy": "^1.6.0",
|
||||
"@whatwg-node/promise-helpers": "^1.3.2",
|
||||
"tslib": "^2.6.3"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -3913,13 +4016,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@graphql-tools/executor-http/node_modules/@whatwg-node/fetch": {
|
||||
"version": "0.10.5",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.10.5.tgz",
|
||||
"integrity": "sha512-+yFJU3hmXPAHJULwx0VzCIsvr/H0lvbPvbOH3areOH3NAuCxCwaJsQ8w6/MwwMcvEWIynSsmAxoyaH04KeosPg==",
|
||||
"version": "0.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.10.7.tgz",
|
||||
"integrity": "sha512-sL31zX8BqZovZc38ovBFmKEfao9AzZ/24sWSHKNhDhcnzIO/PYAX2xF6vYtgU9hinrEGlvScTTyKSMynHGdfEA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@whatwg-node/node-fetch": "^0.7.11",
|
||||
"@whatwg-node/node-fetch": "^0.7.19",
|
||||
"urlpattern-polyfill": "^10.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -3927,15 +4030,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@graphql-tools/executor-http/node_modules/@whatwg-node/node-fetch": {
|
||||
"version": "0.7.17",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.7.17.tgz",
|
||||
"integrity": "sha512-Ni8A2H/r6brNf4u8Y7ATxmWUD0xltsQ6a4NnjWSbw4PgaT34CbY+u4QtVsFj9pTC3dBKJADKjac3AieAig+PZA==",
|
||||
"version": "0.7.20",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.7.20.tgz",
|
||||
"integrity": "sha512-2LI5HkZcdAODb6umb7MUxkWYNUi3j6apgQvIzp+X3w3AVPdvVsshvjaMo4gwLeFtfs+cyMNOLTm9Hhm/TXq6DA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^3.1.1",
|
||||
"@whatwg-node/disposablestack": "^0.0.6",
|
||||
"@whatwg-node/promise-helpers": "^1.2.5",
|
||||
"busboy": "^1.6.0",
|
||||
"@whatwg-node/promise-helpers": "^1.3.2",
|
||||
"tslib": "^2.6.3"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -4114,13 +4217,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/fetch": {
|
||||
"version": "0.10.5",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.10.5.tgz",
|
||||
"integrity": "sha512-+yFJU3hmXPAHJULwx0VzCIsvr/H0lvbPvbOH3areOH3NAuCxCwaJsQ8w6/MwwMcvEWIynSsmAxoyaH04KeosPg==",
|
||||
"version": "0.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.10.7.tgz",
|
||||
"integrity": "sha512-sL31zX8BqZovZc38ovBFmKEfao9AzZ/24sWSHKNhDhcnzIO/PYAX2xF6vYtgU9hinrEGlvScTTyKSMynHGdfEA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@whatwg-node/node-fetch": "^0.7.11",
|
||||
"@whatwg-node/node-fetch": "^0.7.19",
|
||||
"urlpattern-polyfill": "^10.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -4128,15 +4231,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/node-fetch": {
|
||||
"version": "0.7.17",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.7.17.tgz",
|
||||
"integrity": "sha512-Ni8A2H/r6brNf4u8Y7ATxmWUD0xltsQ6a4NnjWSbw4PgaT34CbY+u4QtVsFj9pTC3dBKJADKjac3AieAig+PZA==",
|
||||
"version": "0.7.20",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.7.20.tgz",
|
||||
"integrity": "sha512-2LI5HkZcdAODb6umb7MUxkWYNUi3j6apgQvIzp+X3w3AVPdvVsshvjaMo4gwLeFtfs+cyMNOLTm9Hhm/TXq6DA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^3.1.1",
|
||||
"@whatwg-node/disposablestack": "^0.0.6",
|
||||
"@whatwg-node/promise-helpers": "^1.2.5",
|
||||
"busboy": "^1.6.0",
|
||||
"@whatwg-node/promise-helpers": "^1.3.2",
|
||||
"tslib": "^2.6.3"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -4481,13 +4584,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/fetch": {
|
||||
"version": "0.10.5",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.10.5.tgz",
|
||||
"integrity": "sha512-+yFJU3hmXPAHJULwx0VzCIsvr/H0lvbPvbOH3areOH3NAuCxCwaJsQ8w6/MwwMcvEWIynSsmAxoyaH04KeosPg==",
|
||||
"version": "0.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.10.7.tgz",
|
||||
"integrity": "sha512-sL31zX8BqZovZc38ovBFmKEfao9AzZ/24sWSHKNhDhcnzIO/PYAX2xF6vYtgU9hinrEGlvScTTyKSMynHGdfEA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@whatwg-node/node-fetch": "^0.7.11",
|
||||
"@whatwg-node/node-fetch": "^0.7.19",
|
||||
"urlpattern-polyfill": "^10.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -4495,15 +4598,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/node-fetch": {
|
||||
"version": "0.7.17",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.7.17.tgz",
|
||||
"integrity": "sha512-Ni8A2H/r6brNf4u8Y7ATxmWUD0xltsQ6a4NnjWSbw4PgaT34CbY+u4QtVsFj9pTC3dBKJADKjac3AieAig+PZA==",
|
||||
"version": "0.7.20",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.7.20.tgz",
|
||||
"integrity": "sha512-2LI5HkZcdAODb6umb7MUxkWYNUi3j6apgQvIzp+X3w3AVPdvVsshvjaMo4gwLeFtfs+cyMNOLTm9Hhm/TXq6DA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^3.1.1",
|
||||
"@whatwg-node/disposablestack": "^0.0.6",
|
||||
"@whatwg-node/promise-helpers": "^1.2.5",
|
||||
"busboy": "^1.6.0",
|
||||
"@whatwg-node/promise-helpers": "^1.3.2",
|
||||
"tslib": "^2.6.3"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -4625,13 +4728,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/fetch": {
|
||||
"version": "0.10.5",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.10.5.tgz",
|
||||
"integrity": "sha512-+yFJU3hmXPAHJULwx0VzCIsvr/H0lvbPvbOH3areOH3NAuCxCwaJsQ8w6/MwwMcvEWIynSsmAxoyaH04KeosPg==",
|
||||
"version": "0.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.10.7.tgz",
|
||||
"integrity": "sha512-sL31zX8BqZovZc38ovBFmKEfao9AzZ/24sWSHKNhDhcnzIO/PYAX2xF6vYtgU9hinrEGlvScTTyKSMynHGdfEA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@whatwg-node/node-fetch": "^0.7.11",
|
||||
"@whatwg-node/node-fetch": "^0.7.19",
|
||||
"urlpattern-polyfill": "^10.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -4639,15 +4742,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/node-fetch": {
|
||||
"version": "0.7.17",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.7.17.tgz",
|
||||
"integrity": "sha512-Ni8A2H/r6brNf4u8Y7ATxmWUD0xltsQ6a4NnjWSbw4PgaT34CbY+u4QtVsFj9pTC3dBKJADKjac3AieAig+PZA==",
|
||||
"version": "0.7.20",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.7.20.tgz",
|
||||
"integrity": "sha512-2LI5HkZcdAODb6umb7MUxkWYNUi3j6apgQvIzp+X3w3AVPdvVsshvjaMo4gwLeFtfs+cyMNOLTm9Hhm/TXq6DA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^3.1.1",
|
||||
"@whatwg-node/disposablestack": "^0.0.6",
|
||||
"@whatwg-node/promise-helpers": "^1.2.5",
|
||||
"busboy": "^1.6.0",
|
||||
"@whatwg-node/promise-helpers": "^1.3.2",
|
||||
"tslib": "^2.6.3"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -5018,9 +5121,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@mapbox/node-pre-gyp/node_modules/semver": {
|
||||
"version": "7.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
||||
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
|
|
@ -5785,6 +5888,7 @@
|
|||
"version": "2.8.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
|
||||
"integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
|
|
@ -6050,9 +6154,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": {
|
||||
"version": "7.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
||||
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
|
|
@ -6199,9 +6303,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
|
||||
"version": "7.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
||||
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
|
|
@ -6236,9 +6340,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils/node_modules/semver": {
|
||||
"version": "7.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
||||
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
|
|
@ -6359,9 +6463,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@whatwg-node/promise-helpers": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/promise-helpers/-/promise-helpers-1.3.0.tgz",
|
||||
"integrity": "sha512-486CouizxHXucj8Ky153DDragfkMcHtVEToF5Pn/fInhUUSiCmt9Q4JVBa6UK5q4RammFBtGQ4C9qhGlXU9YbA==",
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@whatwg-node/promise-helpers/-/promise-helpers-1.3.2.tgz",
|
||||
"integrity": "sha512-Nst5JdK47VIl9UcGwtv2Rcgyn5lWtZ0/mhRQ4G8NN2isxpq2TO30iqHzmwoJycjWuyUfg3GFXqP/gFHXeV57IA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
@ -8680,9 +8784,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
||||
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
|
||||
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
|
|
@ -9248,9 +9352,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz",
|
||||
"integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==",
|
||||
"version": "0.25.4",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz",
|
||||
"integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
|
|
@ -9260,31 +9364,31 @@
|
|||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.25.2",
|
||||
"@esbuild/android-arm": "0.25.2",
|
||||
"@esbuild/android-arm64": "0.25.2",
|
||||
"@esbuild/android-x64": "0.25.2",
|
||||
"@esbuild/darwin-arm64": "0.25.2",
|
||||
"@esbuild/darwin-x64": "0.25.2",
|
||||
"@esbuild/freebsd-arm64": "0.25.2",
|
||||
"@esbuild/freebsd-x64": "0.25.2",
|
||||
"@esbuild/linux-arm": "0.25.2",
|
||||
"@esbuild/linux-arm64": "0.25.2",
|
||||
"@esbuild/linux-ia32": "0.25.2",
|
||||
"@esbuild/linux-loong64": "0.25.2",
|
||||
"@esbuild/linux-mips64el": "0.25.2",
|
||||
"@esbuild/linux-ppc64": "0.25.2",
|
||||
"@esbuild/linux-riscv64": "0.25.2",
|
||||
"@esbuild/linux-s390x": "0.25.2",
|
||||
"@esbuild/linux-x64": "0.25.2",
|
||||
"@esbuild/netbsd-arm64": "0.25.2",
|
||||
"@esbuild/netbsd-x64": "0.25.2",
|
||||
"@esbuild/openbsd-arm64": "0.25.2",
|
||||
"@esbuild/openbsd-x64": "0.25.2",
|
||||
"@esbuild/sunos-x64": "0.25.2",
|
||||
"@esbuild/win32-arm64": "0.25.2",
|
||||
"@esbuild/win32-ia32": "0.25.2",
|
||||
"@esbuild/win32-x64": "0.25.2"
|
||||
"@esbuild/aix-ppc64": "0.25.4",
|
||||
"@esbuild/android-arm": "0.25.4",
|
||||
"@esbuild/android-arm64": "0.25.4",
|
||||
"@esbuild/android-x64": "0.25.4",
|
||||
"@esbuild/darwin-arm64": "0.25.4",
|
||||
"@esbuild/darwin-x64": "0.25.4",
|
||||
"@esbuild/freebsd-arm64": "0.25.4",
|
||||
"@esbuild/freebsd-x64": "0.25.4",
|
||||
"@esbuild/linux-arm": "0.25.4",
|
||||
"@esbuild/linux-arm64": "0.25.4",
|
||||
"@esbuild/linux-ia32": "0.25.4",
|
||||
"@esbuild/linux-loong64": "0.25.4",
|
||||
"@esbuild/linux-mips64el": "0.25.4",
|
||||
"@esbuild/linux-ppc64": "0.25.4",
|
||||
"@esbuild/linux-riscv64": "0.25.4",
|
||||
"@esbuild/linux-s390x": "0.25.4",
|
||||
"@esbuild/linux-x64": "0.25.4",
|
||||
"@esbuild/netbsd-arm64": "0.25.4",
|
||||
"@esbuild/netbsd-x64": "0.25.4",
|
||||
"@esbuild/openbsd-arm64": "0.25.4",
|
||||
"@esbuild/openbsd-x64": "0.25.4",
|
||||
"@esbuild/sunos-x64": "0.25.4",
|
||||
"@esbuild/win32-arm64": "0.25.4",
|
||||
"@esbuild/win32-ia32": "0.25.4",
|
||||
"@esbuild/win32-x64": "0.25.4"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-register": {
|
||||
|
|
@ -11834,9 +11938,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/jsonwebtoken/node_modules/semver": {
|
||||
"version": "7.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
||||
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
|
|
@ -12582,9 +12686,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/nodemon/node_modules/semver": {
|
||||
"version": "7.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
||||
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
|
|
@ -14242,9 +14346,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/simple-update-notifier/node_modules/semver": {
|
||||
"version": "7.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
||||
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
|
|
@ -16293,9 +16397,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/yarn-deduplicate/node_modules/semver": {
|
||||
"version": "7.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
||||
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
|
|
|
|||
|
|
@ -18,7 +18,13 @@
|
|||
"@apollo/server": "^4.11.2",
|
||||
"@chakra-ui/react": "^3.15.0",
|
||||
"@chakra-ui/toast": "^7.0.2",
|
||||
"@coolbytes/editorjs-link": "^1.0.0",
|
||||
"@deftomat/opinionated": "^1.1.3",
|
||||
"@editorjs/editorjs": "^2.30.8",
|
||||
"@editorjs/header": "^2.8.8",
|
||||
"@editorjs/link": "^2.6.2",
|
||||
"@editorjs/list": "^2.0.8",
|
||||
"@editorjs/quote": "^2.7.6",
|
||||
"@emotion/react": "^11.13.5",
|
||||
"@hookform/resolvers": "^3.9.1",
|
||||
"@prisma/client": "^6.4.1",
|
||||
|
|
@ -53,8 +59,8 @@
|
|||
"@tanstack/router-devtools": "^1.85.0",
|
||||
"@tanstack/router-plugin": "^1.84.4",
|
||||
"@types/bcrypt": "^5.0.2",
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/cookie-parser": "^1.4.8",
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/jsonwebtoken": "^9.0.9",
|
||||
"@types/node": "^20.9.3",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue