Start work on navigation updates for the library

This commit is contained in:
Jackson Harper 2024-02-07 12:53:04 +08:00
parent 59406ece7e
commit 8b732602a5
8 changed files with 584 additions and 373 deletions

View file

@ -40,7 +40,7 @@ const StyledFallback = styled(Fallback, {
justifyContent: 'center',
fontSize: '15px',
fontWeight: 600,
fontFamily: 'Inter',
fontFamily: '$inter',
color: '$avatarFont',
backgroundColor: '$avatarBg',
})

View file

@ -8,7 +8,7 @@ type AvatarDropdownProps = {
export function AvatarDropdown(props: AvatarDropdownProps): JSX.Element {
return (
<HStack alignment="center" css={{ gap: '6px' }}>
<Avatar height="32px" fallbackText={props.userInitials} />
<Avatar height="25px" fallbackText={props.userInitials} />
</HStack>
)
}

View file

@ -6,347 +6,377 @@ import { currentTheme, updateTheme } from '../../lib/themeUpdater'
import { Avatar } from '../elements/Avatar'
import { AvatarDropdown } from '../elements/AvatarDropdown'
import {
Dropdown,
DropdownOption,
DropdownSeparator,
Dropdown,
DropdownOption,
DropdownSeparator,
} from '../elements/DropdownElements'
import GridLayoutIcon from '../elements/images/GridLayoutIcon'
import ListLayoutIcon from '../elements/images/ListLayoutIcon'
import { Box, HStack, VStack } from '../elements/LayoutPrimitives'
import { Box, HStack, SpanBox, VStack } from '../elements/LayoutPrimitives'
import { StyledText } from '../elements/StyledText'
import { styled, theme, ThemeId } from '../tokens/stitches.config'
import { LayoutType } from './homeFeed/HomeFeedContainer'
import { DropdownMenu } from '@radix-ui/react-dropdown-menu'
type PrimaryDropdownProps = {
children?: ReactNode
showThemeSection: boolean
children?: ReactNode
showThemeSection: boolean
layout?: LayoutType
updateLayout?: (layout: LayoutType) => void
layout?: LayoutType
updateLayout?: (layout: LayoutType) => void
showAddLinkModal?: () => void
showAddLinkModal?: () => void
}
export type HeaderDropdownAction =
| 'navigate-to-install'
| 'navigate-to-feeds'
| 'navigate-to-emails'
| 'navigate-to-labels'
| 'navigate-to-rules'
| 'navigate-to-profile'
| 'navigate-to-subscriptions'
| 'navigate-to-api'
| 'navigate-to-integrations'
| 'navigate-to-saved-searches'
| 'increaseFontSize'
| 'decreaseFontSize'
| 'logout'
| 'navigate-to-install'
| 'navigate-to-feeds'
| 'navigate-to-emails'
| 'navigate-to-labels'
| 'navigate-to-rules'
| 'navigate-to-profile'
| 'navigate-to-subscriptions'
| 'navigate-to-api'
| 'navigate-to-integrations'
| 'navigate-to-saved-searches'
| 'increaseFontSize'
| 'decreaseFontSize'
| 'logout'
type TriggerButtonProps = {
name: string
}
const TriggerButton = (props: TriggerButtonProps): JSX.Element => {
return (
<HStack
css={{
gap: '10px',
alignItems: 'center',
borderRadius: '5px',
height: '27px',
paddingLeft: '5px',
paddingRight: '5px',
'&:hover': {
bg: '#6A6968',
opacity: '0.7px',
},
}}
>
<AvatarDropdown userInitials={props.name.charAt(0) ?? ''} />
<SpanBox
css={{
display: 'flex',
justifyContent: 'center',
fontFamily: '$inter',
fontSize: '12px',
}}
>
{props.name}
</SpanBox>
</HStack>
)
}
export function PrimaryDropdown(props: PrimaryDropdownProps): JSX.Element {
const { viewerData } = useGetViewerQuery()
const router = useRouter()
const { viewerData } = useGetViewerQuery()
const router = useRouter()
const headerDropdownActionHandler = useCallback(
(action: HeaderDropdownAction) => {
switch (action) {
case 'navigate-to-install':
router.push('/settings/installation')
break
case 'navigate-to-feeds':
router.push('/settings/feeds')
break
case 'navigate-to-emails':
router.push('/settings/emails')
break
case 'navigate-to-labels':
router.push('/settings/labels')
break
case 'navigate-to-rules':
router.push('/settings/rules')
break
case 'navigate-to-subscriptions':
router.push('/settings/subscriptions')
break
case 'navigate-to-api':
router.push('/settings/api')
break
case 'navigate-to-integrations':
router.push('/settings/integrations')
break
case 'navigate-to-saved-searches':
router.push('/settings/saved-searches')
break
case 'logout':
document.dispatchEvent(new Event('logout'))
break
default:
break
}
},
[router]
)
const headerDropdownActionHandler = useCallback(
(action: HeaderDropdownAction) => {
switch (action) {
case 'navigate-to-install':
router.push('/settings/installation')
break
case 'navigate-to-feeds':
router.push('/settings/feeds')
break
case 'navigate-to-emails':
router.push('/settings/emails')
break
case 'navigate-to-labels':
router.push('/settings/labels')
break
case 'navigate-to-rules':
router.push('/settings/rules')
break
case 'navigate-to-subscriptions':
router.push('/settings/subscriptions')
break
case 'navigate-to-api':
router.push('/settings/api')
break
case 'navigate-to-integrations':
router.push('/settings/integrations')
break
case 'navigate-to-saved-searches':
router.push('/settings/saved-searches')
break
case 'logout':
document.dispatchEvent(new Event('logout'))
break
default:
break
}
},
[router]
)
if (!viewerData?.me) {
return <></>
}
if (!viewerData?.me) {
return <></>
}
return (
<Dropdown
triggerElement={
props.children ?? (
<AvatarDropdown userInitials={viewerData?.me?.name.charAt(0) ?? ''} />
)
}
css={{ width: '240px' }}
return (
<Dropdown
triggerElement={
props.children ?? <TriggerButton name={viewerData?.me?.name ?? 'O'} />
}
css={{ width: '240px' }}
>
<HStack
alignment="center"
distribution="start"
css={{
width: '100%',
height: '64px',
p: '15px',
gap: '15px',
cursor: 'pointer',
mouseEvents: 'all',
}}
onClick={(event) => {
router.push('/settings/account')
event.preventDefault()
}}
>
<Avatar
imageURL={viewerData.me.profile.pictureUrl}
height="40px"
fallbackText={viewerData?.me?.name.charAt(0) ?? ''}
/>
<VStack
css={{ height: '40px', maxWidth: '240px' }}
alignment="start"
distribution="around"
>
<HStack
alignment="center"
distribution="start"
{viewerData.me && (
<>
<StyledText
css={{
width: '100%',
height: '64px',
p: '15px',
gap: '15px',
cursor: 'pointer',
mouseEvents: 'all',
fontSize: '14px',
fontWeight: '500',
color: '$thTextContrast2',
m: '0px',
p: '0px',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}}
onClick={(event) => {
router.push('/settings/account')
event.preventDefault()
>
{viewerData.me.name}
</StyledText>
<StyledText
css={{
fontSize: '14px',
fontWeight: '400',
color: '#898989',
m: '0px',
p: '0px',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}}
>
<Avatar
imageURL={viewerData.me.profile.pictureUrl}
height="40px"
fallbackText={viewerData?.me?.name.charAt(0) ?? ''}
/>
<VStack
css={{ height: '40px', maxWidth: '240px' }}
alignment="start"
distribution="around"
>
{viewerData.me && (
<>
<StyledText
css={{
fontSize: '14px',
fontWeight: '500',
color: '$thTextContrast2',
m: '0px',
p: '0px',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}}
>
{viewerData.me.name}
</StyledText>
<StyledText
css={{
fontSize: '14px',
fontWeight: '400',
color: '#898989',
m: '0px',
p: '0px',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}}
>
{`@${viewerData.me.profile.username}`}
</StyledText>
</>
)}
</VStack>
</HStack>
<DropdownSeparator />
{props.showThemeSection && <ThemeSection {...props} />}
<DropdownOption
onSelect={() => headerDropdownActionHandler('navigate-to-install')}
title="Install"
/>
<DropdownOption
onSelect={() => headerDropdownActionHandler('navigate-to-feeds')}
title="Feeds"
/>
<DropdownOption
onSelect={() => headerDropdownActionHandler('navigate-to-emails')}
title="Emails"
/>
<DropdownOption
onSelect={() => headerDropdownActionHandler('navigate-to-labels')}
title="Labels"
/>
<DropdownOption
onSelect={() => headerDropdownActionHandler('navigate-to-rules')}
title="Rules"
/>
{props.showAddLinkModal && (
<>
<DropdownSeparator />
>
{`@${viewerData.me.profile.username}`}
</StyledText>
</>
)}
</VStack>
</HStack>
<DropdownSeparator />
{props.showThemeSection && <ThemeSection {...props} />}
<DropdownOption
onSelect={() => headerDropdownActionHandler('navigate-to-install')}
title="Install"
/>
<DropdownOption
onSelect={() => headerDropdownActionHandler('navigate-to-feeds')}
title="Feeds"
/>
<DropdownOption
onSelect={() => headerDropdownActionHandler('navigate-to-emails')}
title="Emails"
/>
<DropdownOption
onSelect={() => headerDropdownActionHandler('navigate-to-labels')}
title="Labels"
/>
<DropdownOption
onSelect={() => headerDropdownActionHandler('navigate-to-rules')}
title="Rules"
/>
<DropdownMenu>
<DropdownOption
onSelect={() => headerDropdownActionHandler('navigate-to-api')}
title="API Keys"
/>
<DropdownOption
onSelect={() =>
headerDropdownActionHandler('navigate-to-integrations')
}
title="Integrations"
/>
</DropdownMenu>
<DropdownOption
onSelect={() => props.showAddLinkModal && props.showAddLinkModal()}
title="Add Link"
/>
</>
)}
<DropdownOption
onSelect={() => headerDropdownActionHandler('navigate-to-api')}
title="API Keys"
/>
<DropdownOption
onSelect={() => headerDropdownActionHandler('navigate-to-integrations')}
title="Integrations"
/>
<DropdownOption
onSelect={() => window.open('https://docs.omnivore.app', '_blank')}
title="Documentation"
/>
<DropdownOption
onSelect={() => window.Intercom('show')}
title="Feedback"
/>
<DropdownSeparator />
<DropdownOption
onSelect={() => headerDropdownActionHandler('logout')}
title="Logout"
/>
</Dropdown>
)
<DropdownOption
onSelect={() => window.open('https://docs.omnivore.app', '_blank')}
title="Documentation"
/>
<DropdownOption
onSelect={() => window.Intercom('show')}
title="Feedback"
/>
<DropdownSeparator />
<DropdownOption
onSelect={() => headerDropdownActionHandler('logout')}
title="Logout"
/>
</Dropdown>
)
}
export const StyledToggleButton = styled('button', {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: '$thTextContrast2',
backgroundColor: 'transparent',
border: 'none',
cursor: 'pointer',
width: '70px',
height: '100%',
borderRadius: '5px',
fontSize: '12px',
fontFamily: '$inter',
gap: '5px',
m: '2px',
'&:hover': {
opacity: 0.8,
},
'&[data-state="on"]': {
bg: '$thBackground',
},
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: '$thTextContrast2',
backgroundColor: 'transparent',
border: 'none',
cursor: 'pointer',
width: '70px',
height: '100%',
borderRadius: '5px',
fontSize: '12px',
fontFamily: '$inter',
gap: '5px',
m: '2px',
'&:hover': {
opacity: 0.8,
},
'&[data-state="on"]': {
bg: '$thBackground',
},
})
function ThemeSection(props: PrimaryDropdownProps): JSX.Element {
return (
<>
<VStack>
<HStack
alignment="center"
css={{
width: '100%',
px: '15px',
justifyContent: 'space-between',
}}
>
<StyledText
css={{
fontSize: '14px',
fontWeight: '400',
cursor: 'default',
color: '$utilityTextDefault',
}}
>
Mode
</StyledText>
<Box
css={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
bg: '$thBackground4',
borderRadius: '5px',
height: '34px',
p: '3px',
px: '1px',
}}
>
<StyledToggleButton
data-state={currentTheme() != ThemeId.Dark ? 'on' : 'off'}
onClick={() => {
updateTheme(ThemeId.Light)
}}
>
Light
<Sun size={15} color={theme.colors.thTextContrast2.toString()} />
</StyledToggleButton>
<StyledToggleButton
data-state={currentTheme() == ThemeId.Dark ? 'on' : 'off'}
onClick={() => {
updateTheme(ThemeId.Dark)
}}
>
Dark
<Moon size={15} color={theme.colors.thTextContrast2.toString()} />
</StyledToggleButton>
</Box>
</HStack>
{props.layout && (
<HStack
alignment="center"
css={{
width: '100%',
px: '15px',
justifyContent: 'space-between',
}}
>
<StyledText
css={{
fontSize: '14px',
fontWeight: '400',
cursor: 'default',
color: '$utilityTextDefault',
}}
>
Layout
</StyledText>
<Box
css={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
bg: '$thBackground4',
borderRadius: '5px',
height: '34px',
p: '3px',
px: '1px',
}}
>
<StyledToggleButton
data-state={props.layout == 'LIST_LAYOUT' ? 'on' : 'off'}
onClick={() => {
props.updateLayout && props.updateLayout('LIST_LAYOUT')
}}
>
<ListLayoutIcon
color={theme.colors.thTextContrast2.toString()}
/>
</StyledToggleButton>
<StyledToggleButton
data-state={props.layout == 'GRID_LAYOUT' ? 'on' : 'off'}
onClick={() => {
props.updateLayout && props.updateLayout('GRID_LAYOUT')
}}
>
<GridLayoutIcon
color={theme.colors.thTextContrast2.toString()}
/>
</StyledToggleButton>
</Box>
</HStack>
)}
</VStack>
<DropdownSeparator />
</>
)
return (
<>
<VStack>
<HStack
alignment="center"
css={{
width: '100%',
px: '15px',
justifyContent: 'space-between',
}}
>
<StyledText
css={{
fontSize: '14px',
fontWeight: '400',
cursor: 'default',
color: '$utilityTextDefault',
}}
>
Mode
</StyledText>
<Box
css={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
bg: '$thBackground4',
borderRadius: '5px',
height: '34px',
p: '3px',
px: '1px',
}}
>
<StyledToggleButton
data-state={currentTheme() != ThemeId.Dark ? 'on' : 'off'}
onClick={() => {
updateTheme(ThemeId.Light)
}}
>
Light
<Sun size={15} color={theme.colors.thTextContrast2.toString()} />
</StyledToggleButton>
<StyledToggleButton
data-state={currentTheme() == ThemeId.Dark ? 'on' : 'off'}
onClick={() => {
updateTheme(ThemeId.Dark)
}}
>
Dark
<Moon size={15} color={theme.colors.thTextContrast2.toString()} />
</StyledToggleButton>
</Box>
</HStack>
{props.layout && (
<HStack
alignment="center"
css={{
width: '100%',
px: '15px',
justifyContent: 'space-between',
}}
>
<StyledText
css={{
fontSize: '14px',
fontWeight: '400',
cursor: 'default',
color: '$utilityTextDefault',
}}
>
Layout
</StyledText>
<Box
css={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
bg: '$thBackground4',
borderRadius: '5px',
height: '34px',
p: '3px',
px: '1px',
}}
>
<StyledToggleButton
data-state={props.layout == 'LIST_LAYOUT' ? 'on' : 'off'}
onClick={() => {
props.updateLayout && props.updateLayout('LIST_LAYOUT')
}}
>
<ListLayoutIcon
color={theme.colors.thTextContrast2.toString()}
/>
</StyledToggleButton>
<StyledToggleButton
data-state={props.layout == 'GRID_LAYOUT' ? 'on' : 'off'}
onClick={() => {
props.updateLayout && props.updateLayout('GRID_LAYOUT')
}}
>
<GridLayoutIcon
color={theme.colors.thTextContrast2.toString()}
/>
</StyledToggleButton>
</Box>
</HStack>
)}
</VStack>
<DropdownSeparator />
</>
)
}

View file

@ -2,7 +2,7 @@ import { usePersistedState } from '../../../lib/hooks/usePersistedState'
import { PinnedSearch } from '../../../pages/settings/pinned-searches'
import { Box } from '../../elements/LayoutPrimitives'
export const DEFAULT_HEADER_HEIGHT = '70px'
export const DEFAULT_HEADER_HEIGHT = '98px'
export const useGetHeaderHeight = () => {
const [hidePinnedSearches] = usePersistedState({
@ -17,7 +17,7 @@ export const useGetHeaderHeight = () => {
})
if (hidePinnedSearches || !pinnedSearches?.length) {
return '70px'
return '98px'
}
return '100px'
}

View file

@ -19,8 +19,11 @@ import { SavedSearch } from '../../../lib/networking/fragments/savedSearchFragme
import { ToggleCaretDownIcon } from '../../elements/icons/ToggleCaretDownIcon'
import Link from 'next/link'
import { ToggleCaretRightIcon } from '../../elements/icons/ToggleCaretRightIcon'
import { SplitButton } from '../../elements/SplitButton'
import { AvatarDropdown } from '../../elements/AvatarDropdown'
import { PrimaryDropdown } from '../PrimaryDropdown'
export const LIBRARY_LEFT_MENU_WIDTH = '233px'
export const LIBRARY_LEFT_MENU_WIDTH = '275px'
type LibraryFilterMenuProps = {
setShowAddLinkModal: (show: boolean) => void
@ -119,6 +122,7 @@ export function LibraryFilterMenu(props: LibraryFilterMenuProps): JSX.Element {
<SavedSearches {...props} savedSearches={savedSearches} />
<Subscriptions {...props} subscriptions={subscriptions} />
<Labels {...props} labels={labels} />
<Footer />
<Box css={{ height: '250px ' }} />
</Box>
{/* This spacer pushes library content to the right of
@ -241,8 +245,16 @@ function Subscriptions(
>
{!collapsed ? (
<>
<FilterButton filterTerm="in:inbox has:subscriptions" text="All" {...props} />
<FilterButton filterTerm={`in:inbox label:RSS`} text="Feeds" {...props} />
<FilterButton
filterTerm="in:inbox has:subscriptions"
text="All"
{...props}
/>
<FilterButton
filterTerm={`in:inbox label:RSS`}
text="Feeds"
{...props}
/>
<FilterButton
filterTerm={`in:inbox label:Newsletter`}
text="Newsletters"
@ -598,3 +610,38 @@ function EditButton(props: EditButtonProps): JSX.Element {
</Link>
)
}
const Footer = (): JSX.Element => {
return (
<HStack
css={{
gap: '10px',
height: '55px',
position: 'fixed',
bottom: '0%',
alignItems: 'center',
padding: '5px',
backgroundColor: '$thBackground2',
width: LIBRARY_LEFT_MENU_WIDTH,
overflowY: 'auto',
overflowX: 'hidden',
'&::-webkit-scrollbar': {
display: 'none',
},
'@mdDown': {
width: '100%',
},
}}
>
<PrimaryDropdown
showThemeSection={true}
showAddLinkModal={() => {
console.log('show')
}}
/>
<SpanBox css={{ marginLeft: 'auto', marginRight: '5px' }}>
<SplitButton title="Add Link" />
</SpanBox>
</HStack>
)
}

View file

@ -37,6 +37,10 @@ import { CaretDownIcon } from '../../elements/icons/CaretDownIcon'
import { PinnedButtons } from './PinnedButtons'
import { usePersistedState } from '../../../lib/hooks/usePersistedState'
import { PinnedSearch } from '../../../pages/settings/pinned-searches'
import { HeaderCheckboxIcon } from '../../elements/icons/HeaderCheckboxIcon'
import { HeaderSearchIcon } from '../../elements/icons/HeaderSearchIcon'
import { HeaderToggleGridIcon } from '../../elements/icons/HeaderToggleGridIcon'
import { HeaderToggleListIcon } from '../../elements/icons/HeaderToggleListIcon'
export type MultiSelectMode = 'off' | 'none' | 'some' | 'visible' | 'search'
@ -92,6 +96,16 @@ const controlWidths = (
export function LibraryHeader(props: LibraryHeaderProps): JSX.Element {
const headerHeight = useGetHeaderHeight()
const [small, setSmall] = useState(false)
useEffect(() => {
if (typeof window !== 'undefined') {
window.addEventListener('scroll', () =>
setSmall(window.pageYOffset > 200)
)
}
}, [])
return (
<>
<VStack
@ -103,12 +117,13 @@ export function LibraryHeader(props: LibraryHeaderProps): JSX.Element {
left: LIBRARY_LEFT_MENU_WIDTH,
zIndex: 5,
position: 'fixed',
height: headerHeight,
bg: '$thLibraryBackground',
height: small ? '60px' : DEFAULT_HEADER_HEIGHT,
bg: 'red',
transition: '0.5s',
'@mdDown': {
left: '0px',
right: '0',
height: DEFAULT_HEADER_HEIGHT,
height: small ? '60px' : DEFAULT_HEADER_HEIGHT,
},
}}
>
@ -132,12 +147,24 @@ function LargeHeaderLayout(props: LibraryHeaderProps): JSX.Element {
initialValue: [],
isSessionStorage: false,
})
const [small, setSmall] = useState(false)
useEffect(() => {
if (typeof window !== 'undefined') {
window.addEventListener('scroll', () =>
setSmall(window.pageYOffset > 200)
)
}
}, [])
return (
<HStack
alignment="center"
distribution="center"
distribution="start"
css={{
gap: '10px',
paddingLeft: '50px',
paddingRight: '50px',
width: '100%',
height: '100%',
'@mdDown': {
@ -145,39 +172,16 @@ function LargeHeaderLayout(props: LibraryHeaderProps): JSX.Element {
},
}}
>
<VStack alignment="center" distribution="start">
<ControlButtonBox
layout={props.layout}
updateLayout={props.updateLayout}
numItemsSelected={props.numItemsSelected}
multiSelectMode={props.multiSelectMode}
setMultiSelectMode={props.setMultiSelectMode}
showAddLinkModal={props.showAddLinkModal}
performMultiSelectAction={props.performMultiSelectAction}
searchTerm={props.searchTerm}
applySearchQuery={props.applySearchQuery}
allowSelectMultiple={props.allowSelectMultiple}
handleLinkSubmission={props.handleLinkSubmission}
/>
<SpanBox
css={{
...controlWidths(props.layout, props.multiSelectMode),
maxWidth: '587px',
alignSelf: 'flex-start',
'-ms-overflow-style': 'none',
scrollbarWidth: 'none',
'::-webkit-scrollbar': {
display: 'none',
},
}}
>
<PinnedButtons
items={pinnedSearches ?? []}
searchTerm={props.searchTerm}
applySearchQuery={props.applySearchQuery}
/>
</SpanBox>
</VStack>
<HeaderCheckboxIcon />
<HeaderSearchIcon />
<SpanBox css={{ display: 'flex', marginLeft: 'auto' }}>
{props.layout == 'LIST_LAYOUT' ? (
<HeaderToggleGridIcon />
) : (
<HeaderToggleListIcon />
)}
</SpanBox>
</HStack>
)
}
@ -588,10 +592,6 @@ function SearchControlButtonBox(
<GridViewIcon size={30} color={'#898989'} />
)}
</Button>
<PrimaryDropdown
showThemeSection={true}
showAddLinkModal={props.showAddLinkModal}
/>
</>
)
}

View file

@ -178,6 +178,7 @@ export const { styled, css, theme, getCssText, globalCss, keyframes, config } =
thLibraryMenuSecondary: '#3D3D3D',
thLibraryMenuUnselected: '#898989',
thLibrarySelectionColor: '#FFEA9F',
thLibraryNavigationMenuFooter: '#EFEADE',
thNotebookSubtle: '#6A6968',
thNotebookBorder: '#D9D9D9',
@ -283,13 +284,14 @@ const darkThemeSpec = {
thBackground5: '#3D3D3D',
thBackgroundActive: '#3D3D3D',
thBackgroundContrast: '#000000',
thLeftMenuBackground: '#1D1D1D',
thLeftMenuBackground: '#343434',
thLibraryBackground: '#333333',
thLibrarySearchbox: '#3D3D3D',
thLibraryMenuPrimary: '#EBEBEB',
thLibraryMenuSecondary: '#EBEBEB',
thLibraryMenuUnselected: '#898989',
thLibrarySelectionColor: '#3D3D3D',
thLibraryNavigationMenuFooter: '#3D3D3D',
thNotebookSubtle: '#898989',
thNotebookBorder: '#3D3D3D',

152
yarn.lock
View file

@ -5459,6 +5459,40 @@
resolved "https://registry.yarnpkg.com/@reach/observe-rect/-/observe-rect-1.2.0.tgz#d7a6013b8aafcc64c778a0ccb83355a11204d3b2"
integrity sha512-Ba7HmkFgfQxZqqaeIWWkNK0rEhpxVQHIoVyW1YDSkGsGIXzcaW4deC8B0pZrNSSyLTdIk7y+5olKt5+g0GmFIQ==
"@redis/bloom@1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@redis/bloom/-/bloom-1.2.0.tgz#d3fd6d3c0af3ef92f26767b56414a370c7b63b71"
integrity sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==
"@redis/client@1.5.14":
version "1.5.14"
resolved "https://registry.yarnpkg.com/@redis/client/-/client-1.5.14.tgz#1107893464d092f140d77c468b018a6ed306a180"
integrity sha512-YGn0GqsRBFUQxklhY7v562VMOP0DcmlrHHs3IV1mFE3cbxe31IITUkqhBcIhVSI/2JqtWAJXg5mjV4aU+zD0HA==
dependencies:
cluster-key-slot "1.1.2"
generic-pool "3.9.0"
yallist "4.0.0"
"@redis/graph@1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@redis/graph/-/graph-1.1.1.tgz#8c10df2df7f7d02741866751764031a957a170ea"
integrity sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==
"@redis/json@1.0.6":
version "1.0.6"
resolved "https://registry.yarnpkg.com/@redis/json/-/json-1.0.6.tgz#b7a7725bbb907765d84c99d55eac3fcf772e180e"
integrity sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==
"@redis/search@1.1.6":
version "1.1.6"
resolved "https://registry.yarnpkg.com/@redis/search/-/search-1.1.6.tgz#33bcdd791d9ed88ab6910243a355d85a7fedf756"
integrity sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==
"@redis/time-series@1.0.5":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@redis/time-series/-/time-series-1.0.5.tgz#a6d70ef7a0e71e083ea09b967df0a0ed742bc6ad"
integrity sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==
"@remusao/guess-url-type@^1.1.2":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@remusao/guess-url-type/-/guess-url-type-1.2.1.tgz#b3e7c32abdf98d0fb4f93cc67cad580b5fe4ba57"
@ -6010,6 +6044,11 @@
resolved "https://registry.yarnpkg.com/@sqltools/formatter/-/formatter-1.2.3.tgz#1185726610acc37317ddab11c3c7f9066966bd20"
integrity sha512-O3uyB/JbkAEMZaP3YqyHH7TMnex7tWyCbCI4EfJdOCoN6HIhqdJBWTM6aCCiWQ/5f5wxjgU735QAIpJbjDvmzg==
"@sqltools/formatter@^1.2.5":
version "1.2.5"
resolved "https://registry.yarnpkg.com/@sqltools/formatter/-/formatter-1.2.5.tgz#3abc203c79b8c3e90fd6c156a0c62d5403520e12"
integrity sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==
"@stitches/react@^1.2.5":
version "1.2.8"
resolved "https://registry.yarnpkg.com/@stitches/react/-/react-1.2.8.tgz#954f8008be8d9c65c4e58efa0937f32388ce3a38"
@ -7427,6 +7466,16 @@
"@types/qs" "*"
"@types/serve-static" "*"
"@types/express@^4.17.21":
version "4.17.21"
resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d"
integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==
dependencies:
"@types/body-parser" "*"
"@types/express-serve-static-core" "^4.17.33"
"@types/qs" "*"
"@types/serve-static" "*"
"@types/filesystem@*":
version "0.0.32"
resolved "https://registry.yarnpkg.com/@types/filesystem/-/filesystem-0.0.32.tgz#307df7cc084a2293c3c1a31151b178063e0a8edf"
@ -7828,6 +7877,13 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.68.tgz#3155f64a961b3d8d10246c80657f9a7292e3421a"
integrity sha512-sG3hPIQwJLoewrN7cr0dwEy+yF5nD4D/4FxtQpFciRD/xwUzgD+G05uxZHv5mhfXo4F9Jkp13jjn0CC2q325sg==
"@types/node@^20.11.0":
version "20.11.16"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.16.tgz#4411f79411514eb8e2926f036c86c9f0e4ec6708"
integrity sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==
dependencies:
undici-types "~5.26.4"
"@types/nodemailer@^6.4.4":
version "6.4.4"
resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.4.tgz#c265f7e7a51df587597b3a49a023acaf0c741f4b"
@ -9359,6 +9415,11 @@ app-root-path@^3.0.0:
resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.0.0.tgz#210b6f43873227e18a4b810a032283311555d5ad"
integrity sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==
app-root-path@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.1.0.tgz#5971a2fc12ba170369a7a1ef018c71e6e47c2e86"
integrity sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==
apparatus@^0.0.10:
version "0.0.10"
resolved "https://registry.yarnpkg.com/apparatus/-/apparatus-0.0.10.tgz#81ea756772ada77863db54ceee8202c109bdca3e"
@ -11669,7 +11730,7 @@ clsx@^1.1.1:
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
cluster-key-slot@^1.1.0:
cluster-key-slot@1.1.2, cluster-key-slot@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac"
integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==
@ -12805,7 +12866,7 @@ dateformat@^3.0.0, dateformat@^3.0.3:
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==
dayjs@1.x, dayjs@^1.10.4, dayjs@^1.11.7:
dayjs@1.x, dayjs@^1.10.4, dayjs@^1.11.7, dayjs@^1.11.9:
version "1.11.10"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0"
integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==
@ -13528,6 +13589,11 @@ dotenv@^16.0.1:
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.1.tgz#8f8f9d94876c35dac989876a5d3a82a267fdce1d"
integrity sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==
dotenv@^16.0.3:
version "16.4.1"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.1.tgz#1d9931f1d3e5d2959350d1250efab299561f7f11"
integrity sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==
dotenv@^8.0.0, dotenv@^8.2.0:
version "8.6.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b"
@ -14808,7 +14874,7 @@ express-rate-limit@^6.3.0:
resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-6.11.1.tgz#52e05c5d379cd5d06ae29665862436eb712e414a"
integrity sha512-8+UpWtQY25lJaa4+3WxDBGDcAu4atcTruSs3QSL5VPEplYy6kmk84wutG9rUkkK5LmMQQ7TFHWLZYITwVNbbEg==
express@^4.16.4, express@^4.17.1:
express@^4.16.4, express@^4.17.1, express@^4.18.2:
version "4.18.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
@ -15855,6 +15921,11 @@ gcp-metadata@^6.0.0:
gaxios "^6.0.0"
json-bigint "^1.0.0"
generic-pool@3.9.0:
version "3.9.0"
resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-3.9.0.tgz#36f4a678e963f4fdb8707eab050823abc4e8f5e4"
integrity sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==
gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2:
version "1.0.0-beta.2"
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
@ -16159,7 +16230,7 @@ glob@7.2.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glo
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^10.2.2:
glob@^10.2.2, glob@^10.3.10:
version "10.3.10"
resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b"
integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==
@ -21853,6 +21924,11 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
mkdirp@^2.1.3:
version "2.1.6"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.6.tgz#964fbcb12b2d8c5d6fbc62a963ac95a273e2cc19"
integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==
mkdirp@~0.3.5:
version "0.3.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7"
@ -26055,6 +26131,14 @@ read-pkg@^7.1.0:
parse-json "^5.2.0"
type-fest "^2.0.0"
read-yaml-file@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/read-yaml-file/-/read-yaml-file-2.1.0.tgz#c5866712db9ef5343b4d02c2413bada53c41c4a9"
integrity sha512-UkRNRIwnhG+y7hpqnycCL/xbTk7+ia9VuVTC0S+zVbwd65DI9eUpRMfsWIGrCWxTU/mi+JW8cHQCrv+zfCbEPQ==
dependencies:
js-yaml "^4.0.0"
strip-bom "^4.0.0"
read@1, read@^1.0.7, read@~1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4"
@ -26192,11 +26276,28 @@ redis-parser@^3.0.0:
dependencies:
redis-errors "^1.0.0"
redis@^4.3.1:
version "4.6.13"
resolved "https://registry.yarnpkg.com/redis/-/redis-4.6.13.tgz#e247267c5f3ba35ab8277b57343d3a56acb2f0a6"
integrity sha512-MHgkS4B+sPjCXpf+HfdetBwbRz6vCtsceTmw1pHNYJAsYxrfpOP6dz+piJWGos8wqG7qb3vj/Rrc5qOlmInUuA==
dependencies:
"@redis/bloom" "1.2.0"
"@redis/client" "1.5.14"
"@redis/graph" "1.1.1"
"@redis/json" "1.0.6"
"@redis/search" "1.1.6"
"@redis/time-series" "1.0.5"
reflect-metadata@^0.1.13:
version "0.1.13"
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08"
integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==
reflect-metadata@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.1.tgz#8d5513c0f5ef2b4b9c3865287f3c0940c1f67f74"
integrity sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==
reflect.getprototypeof@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3"
@ -29215,7 +29316,7 @@ tslib@^1.0.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tslib@^2, tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1, tslib@^2.4.0:
tslib@^2, tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1, tslib@^2.4.0, tslib@^2.5.0:
version "2.6.2"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
@ -29431,6 +29532,27 @@ typeorm-naming-strategies@^4.1.0:
resolved "https://registry.yarnpkg.com/typeorm-naming-strategies/-/typeorm-naming-strategies-4.1.0.tgz#1ec6eb296c8d7b69bb06764d5b9083ff80e814a9"
integrity sha512-vPekJXzZOTZrdDvTl1YoM+w+sUIfQHG4kZTpbFYoTsufyv9NIBRe4Q+PdzhEAFA2std3D9LZHEb1EjE9zhRpiQ==
typeorm@^0.3.19:
version "0.3.20"
resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.3.20.tgz#4b61d737c6fed4e9f63006f88d58a5e54816b7ab"
integrity sha512-sJ0T08dV5eoZroaq9uPKBoNcGslHBR4E4y+EBHs//SiGbblGe7IeduP/IH4ddCcj0qp3PHwDwGnuvqEAnKlq/Q==
dependencies:
"@sqltools/formatter" "^1.2.5"
app-root-path "^3.1.0"
buffer "^6.0.3"
chalk "^4.1.2"
cli-highlight "^2.1.11"
dayjs "^1.11.9"
debug "^4.3.4"
dotenv "^16.0.3"
glob "^10.3.10"
mkdirp "^2.1.3"
reflect-metadata "^0.2.1"
sha.js "^2.4.11"
tslib "^2.5.0"
uuid "^9.0.0"
yargs "^17.6.2"
typeorm@^0.3.4:
version "0.3.7"
resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.3.7.tgz#5776ed5058f0acb75d64723b39ff458d21de64c1"
@ -29469,6 +29591,11 @@ typescript@^4.4.4:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
typescript@^5.3.3:
version "5.3.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37"
integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==
ua-parser-js@^0.7.30:
version "0.7.33"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.33.tgz#1d04acb4ccef9293df6f70f2c3d22f3030d8b532"
@ -29547,6 +29674,11 @@ underscore@^1.13.4, underscore@^1.9.1:
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.4.tgz#7886b46bbdf07f768e0052f1828e1dcab40c0dee"
integrity sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ==
undici-types@~5.26.4:
version "5.26.5"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
undici@^4.9.3:
version "4.14.1"
resolved "https://registry.yarnpkg.com/undici/-/undici-4.14.1.tgz#7633b143a8a10d6d63335e00511d071e8d52a1d9"
@ -31027,6 +31159,11 @@ y18n@^5.0.5:
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
yallist@4.0.0, yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yallist@^2.0.0, yallist@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
@ -31037,11 +31174,6 @@ yallist@^3.0.2:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yaml-ast-parser@^0.0.43:
version "0.0.43"
resolved "https://registry.yarnpkg.com/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz#e8a23e6fb4c38076ab92995c5dca33f3d3d7c9bb"