diff --git a/frontend/packages/data-portal/.gitignore b/frontend/packages/data-portal/.gitignore index 68c5d18f0..516a31143 100644 --- a/frontend/packages/data-portal/.gitignore +++ b/frontend/packages/data-portal/.gitignore @@ -1,3 +1,4 @@ +coverage/ node_modules/ /test-results/ /playwright-report/ diff --git a/frontend/packages/data-portal/app/components/AuthorLegend.tsx b/frontend/packages/data-portal/app/components/AuthorLegend.tsx index e07c6b3a0..dd2c7d3ed 100644 --- a/frontend/packages/data-portal/app/components/AuthorLegend.tsx +++ b/frontend/packages/data-portal/app/components/AuthorLegend.tsx @@ -42,7 +42,9 @@ export function AuthorLegend({ inline = false }: { inline?: boolean }) { } classes={{ - tooltip: '!p-sds-m !min-w-fit border-solid border border-sds-gray-300', + tooltip: + // need to specify background color because it's not visible locally + '!p-sds-m !min-w-fit border-solid border border-sds-gray-300 !bg-white', }} placement="top-start" > diff --git a/frontend/packages/data-portal/app/components/AuthorLink/AuthorLink.mock.tsx b/frontend/packages/data-portal/app/components/AuthorLink/AuthorLink.mock.tsx new file mode 100644 index 000000000..f503b2baf --- /dev/null +++ b/frontend/packages/data-portal/app/components/AuthorLink/AuthorLink.mock.tsx @@ -0,0 +1,18 @@ +import { ComponentProps } from 'react' + +import { MockLinkComponent } from 'app/components/Link' + +import { AuthorLink } from './AuthorLink' + +export function MockAuthorLink({ + author, + large, +}: ComponentProps) { + return ( + + ) +} diff --git a/frontend/packages/data-portal/app/components/AuthorLink/AuthorLink.test.tsx b/frontend/packages/data-portal/app/components/AuthorLink/AuthorLink.test.tsx new file mode 100644 index 000000000..29f81f3e1 --- /dev/null +++ b/frontend/packages/data-portal/app/components/AuthorLink/AuthorLink.test.tsx @@ -0,0 +1,62 @@ +import { it } from '@jest/globals' +import { render, screen } from '@testing-library/react' +import { pick } from 'lodash-es' + +import { MockLinkComponent } from 'app/components/Link' +import { TestIds } from 'app/constants/testIds' + +import { AuthorLink } from './AuthorLink' +import { ORC_ID_URL } from './constants' +import { AuthorInfo } from './types' + +const DEFAULT_AUTHOR: AuthorInfo = { + corresponding_author_status: true, + email: 'actin.filament@gmail.com', + name: 'Actin Filament', + orcid: '0000-0000-0000-0000', + primary_author_status: false, +} + +it('should not be link if orc ID is not provided', () => { + render() + expect(screen.queryByRole('link')).not.toBeInTheDocument() +}) + +it('should be a link if orc ID is provided', () => { + render( + , + ) + + const link = screen.getByRole('link') + expect(link).toBeInTheDocument() + expect(link).toHaveProperty('href', `${ORC_ID_URL}/${DEFAULT_AUTHOR.orcid}`) + expect(screen.getByTestId(TestIds.OrcIdIcon)).toBeInTheDocument() +}) + +it('should have icon if user is corresponding author', () => { + render( + , + ) + + expect(screen.getByTestId(TestIds.EnvelopeIcon)).toBeInTheDocument() +}) + +it('should use regular icon size', () => { + render() + + const text = screen.getByText(DEFAULT_AUTHOR.name) + expect(text).toHaveClass('text-xs') +}) + +it('should use large icon size', () => { + render() + + const text = screen.getByText(DEFAULT_AUTHOR.name) + expect(text).toHaveClass('text-sm') +}) diff --git a/frontend/packages/data-portal/app/components/AuthorLink/AuthorLink.tsx b/frontend/packages/data-portal/app/components/AuthorLink/AuthorLink.tsx new file mode 100644 index 000000000..b9256da4b --- /dev/null +++ b/frontend/packages/data-portal/app/components/AuthorLink/AuthorLink.tsx @@ -0,0 +1,70 @@ +import { LinkProps } from '@remix-run/react' +import { ComponentType } from 'react' + +import { EnvelopeIcon, ORCIDIcon } from 'app/components/icons' +import { Link } from 'app/components/Link' +import { cns } from 'app/utils/cns' + +import { ORC_ID_URL } from './constants' +import { AuthorInfo } from './types' + +const BASE_ICON_SIZE_PX = 10 +const LARGE_ICON_SIZE_PX = 14 + +export function AuthorLink({ + author, + large, + LinkComponent = Link, +}: { + author: AuthorInfo + large?: boolean + LinkComponent?: ComponentType +}) { + const iconSize = large ? LARGE_ICON_SIZE_PX : BASE_ICON_SIZE_PX + const content = ( + + + {author.orcid && ( + + )} + + + {author.name} + + + + {author.corresponding_author_status && ( + + )} + + ) + + if (author.orcid) { + return ( + + {content} + + ) + } + + return content +} diff --git a/frontend/packages/data-portal/app/components/AuthorLink/constants.ts b/frontend/packages/data-portal/app/components/AuthorLink/constants.ts new file mode 100644 index 000000000..7d80a89de --- /dev/null +++ b/frontend/packages/data-portal/app/components/AuthorLink/constants.ts @@ -0,0 +1 @@ +export const ORC_ID_URL = 'https://orcid.org' diff --git a/frontend/packages/data-portal/app/components/AuthorLink/index.ts b/frontend/packages/data-portal/app/components/AuthorLink/index.ts new file mode 100644 index 000000000..c07b6d24b --- /dev/null +++ b/frontend/packages/data-portal/app/components/AuthorLink/index.ts @@ -0,0 +1,3 @@ +export * from './AuthorLink' +export * from './AuthorLink.mock' +export * from './types' diff --git a/frontend/packages/data-portal/app/components/AuthorLink/types.ts b/frontend/packages/data-portal/app/components/AuthorLink/types.ts new file mode 100644 index 000000000..a2fc4dc65 --- /dev/null +++ b/frontend/packages/data-portal/app/components/AuthorLink/types.ts @@ -0,0 +1,10 @@ +import { Dataset_Authors } from 'app/__generated__/graphql' + +export type AuthorInfo = Pick< + Dataset_Authors, + | 'corresponding_author_status' + | 'email' + | 'name' + | 'orcid' + | 'primary_author_status' +> diff --git a/frontend/packages/data-portal/app/components/BrowseData/DatasetTable.tsx b/frontend/packages/data-portal/app/components/BrowseData/DatasetTable.tsx index de6a8afa1..494934afa 100644 --- a/frontend/packages/data-portal/app/components/BrowseData/DatasetTable.tsx +++ b/frontend/packages/data-portal/app/components/BrowseData/DatasetTable.tsx @@ -156,11 +156,7 @@ export function DatasetTable() { /> ) : ( - + )}

diff --git a/frontend/packages/data-portal/app/components/Dataset/DatasetAuthors.test.tsx b/frontend/packages/data-portal/app/components/Dataset/DatasetAuthors.test.tsx new file mode 100644 index 000000000..8e5b019b2 --- /dev/null +++ b/frontend/packages/data-portal/app/components/Dataset/DatasetAuthors.test.tsx @@ -0,0 +1,127 @@ +import { render, screen } from '@testing-library/react' + +import { AuthorInfo, MockAuthorLink } from 'app/components/AuthorLink' + +import { DatasetAuthors } from './DatasetAuthors' + +const DEFAULT_AUTHORS: AuthorInfo[] = [ + { name: 'Foo', corresponding_author_status: true }, + { name: 'Bar' }, + { name: 'Foo Bar', primary_author_status: true }, + { name: 'Foobar Foo' }, + { name: 'Foo Bar 2', primary_author_status: true }, + { name: 'Foo 2', corresponding_author_status: true }, + { name: 'Bar 2' }, +] + +const AUTHOR_MAP = Object.fromEntries( + DEFAULT_AUTHORS.map((author) => [author.name, author]), +) + +it('should render authors', () => { + render() + + DEFAULT_AUTHORS.forEach((author) => + expect(screen.getByText(author.name)).toBeInTheDocument(), + ) +}) + +it('should sort primary authors', () => { + render() + const authorNode = screen.getByRole('paragraph') + const authors = (authorNode.textContent ?? '').split(', ') + + expect(AUTHOR_MAP[authors[0]].primary_author_status).toBe(true) + expect(AUTHOR_MAP[authors[1]].primary_author_status).toBe(true) +}) + +it('should sort other authors', () => { + render() + const authorNode = screen.getByRole('paragraph') + const authors = (authorNode.textContent ?? '').split(', ') + const otherAuthors = authors.slice(2, -2) + + otherAuthors.forEach((author) => { + expect(AUTHOR_MAP[author].primary_author_status).toBeUndefined() + expect(AUTHOR_MAP[author].corresponding_author_status).toBeUndefined() + }) +}) + +it('should sort corresponding authors', () => { + render() + const authorNode = screen.getByRole('paragraph') + const authors = (authorNode.textContent ?? '').split(', ') + + expect(AUTHOR_MAP[authors.at(-1) ?? ''].corresponding_author_status).toBe( + true, + ) + expect(AUTHOR_MAP[authors.at(-2) ?? ''].corresponding_author_status).toBe( + true, + ) +}) + +it('should render author links', () => { + const authors = DEFAULT_AUTHORS.map((author, idx) => ({ + ...author, + orcid: `0000-0000-0000-000${idx}`, + })) + + render( + , + ) + + authors.forEach((author) => + expect( + screen.getByRole('link', { name: `${author.name}` }), + ).toBeInTheDocument(), + ) +}) + +it('should not render author links when compact', () => { + const authors = DEFAULT_AUTHORS.map((author, idx) => ({ + ...author, + orcid: `0000-0000-0000-000${idx}`, + })) + + render( + , + ) + + expect(screen.queryByRole('link')).not.toBeInTheDocument() +}) + +it('should not render other authors when compact', () => { + render() + const authorNode = screen.getByRole('paragraph') + const authors = (authorNode.textContent ?? '').split(', ') + const otherAuthors = authors.slice(2, -2) + + otherAuthors.forEach((author) => + expect(screen.queryByText(author)).not.toBeInTheDocument(), + ) +}) + +it('should render comma if compact and has corresponding authors', () => { + render() + expect(screen.getByText((text) => text.includes('... ,'))).toBeInTheDocument() +}) + +it('should not render comma for others if compact and no corresponding authors', () => { + render( + !author.corresponding_author_status, + )} + compact + />, + ) + + expect(screen.getByText((text) => text.includes('...'))).toBeInTheDocument() + expect( + screen.queryByText((text) => text.includes('... ,')), + ).not.toBeInTheDocument() +}) diff --git a/frontend/packages/data-portal/app/components/Dataset/DatasetAuthors.tsx b/frontend/packages/data-portal/app/components/Dataset/DatasetAuthors.tsx index 76c22d022..9eb2e29f2 100644 --- a/frontend/packages/data-portal/app/components/Dataset/DatasetAuthors.tsx +++ b/frontend/packages/data-portal/app/components/Dataset/DatasetAuthors.tsx @@ -1,30 +1,31 @@ -import { Fragment, useMemo } from 'react' +import { ComponentProps, ComponentType, Fragment, useMemo } from 'react' -import { Dataset_Authors } from 'app/__generated__/graphql' -import { EnvelopeIcon } from 'app/components/icons' -import { Link } from 'app/components/Link' +import { AuthorInfo, AuthorLink } from 'app/components/AuthorLink' import { cns } from 'app/utils/cns' -export type AuthorInfo = Pick< - Dataset_Authors, - 'name' | 'primary_author_status' | 'corresponding_author_status' | 'email' -> - function getAuthorKey(author: AuthorInfo) { return author.name + author.email } +const SEPARATOR = `, ` + +function getAuthorIds(authors: AuthorInfo[]) { + return authors.map((author) => author.name + author.email + author.orcid) +} + export function DatasetAuthors({ + AuthorLinkComponent = AuthorLink, authors, className, - separator = ';', compact = false, + large, subtle = false, }: { + AuthorLinkComponent?: ComponentType> authors: AuthorInfo[] className?: string - separator?: string compact?: boolean + large?: boolean subtle?: boolean }) { // TODO: make the below grouping more efficient and/or use GraphQL ordering @@ -39,10 +40,6 @@ export function DatasetAuthors({ !(author.primary_author_status || author.corresponding_author_status), ) - const envelopeIcon = ( - - ) - const otherCollapsed = useMemo(() => { const ellipsis = '...' @@ -50,10 +47,18 @@ export function DatasetAuthors({ if (authorsCorresponding.length === 0) { return ellipsis } - return `${ellipsis} ${separator} ` + return `${ellipsis} ${SEPARATOR}` } return null - }, [authorsOther, authorsCorresponding, compact, separator]) + }, [ + authorsCorresponding.length, + authorsOther.length, + compact, + // eslint-disable-next-line react-hooks/exhaustive-deps + getAuthorIds(authorsCorresponding), + // eslint-disable-next-line react-hooks/exhaustive-deps + getAuthorIds(authorsOther), + ]) // TODO: let's find a better way of doing this return ( @@ -61,34 +66,38 @@ export function DatasetAuthors({ {authorsPrimary.map((author, i, arr) => ( - {author.name} + {compact ? ( + author.name + ) : ( + + )} {!( authorsOther.length + authorsCorresponding.length === 0 && arr.length - 1 === i - ) && `${separator} `} + ) && SEPARATOR} ))} + {compact ? otherCollapsed : authorsOther.map((author, i, arr) => ( - {author.name} + {!(authorsCorresponding.length === 0 && arr.length - 1 === i) && - `${separator} `} + SEPARATOR} ))} + {authorsCorresponding.map((author, i, arr) => ( - {author.name} - {!compact && - (author.email ? ( - {envelopeIcon} - ) : ( - envelopeIcon - ))} - {!(arr.length - 1 === i) && `${separator} `} + {compact ? ( + author.name + ) : ( + + )} + {!(arr.length - 1 === i) && SEPARATOR} ))} diff --git a/frontend/packages/data-portal/app/components/Dataset/DatasetMetadataTable.tsx b/frontend/packages/data-portal/app/components/Dataset/DatasetMetadataTable.tsx index 3a5d604cd..d67edf354 100644 --- a/frontend/packages/data-portal/app/components/Dataset/DatasetMetadataTable.tsx +++ b/frontend/packages/data-portal/app/components/Dataset/DatasetMetadataTable.tsx @@ -3,12 +3,13 @@ import { isString } from 'lodash-es' import { AccordionMetadataTable } from 'app/components/AccordionMetadataTable' import { AuthorLegend } from 'app/components/AuthorLegend' +import { AuthorInfo } from 'app/components/AuthorLink' import { DatabaseEntry } from 'app/components/DatabaseEntry' import { Link } from 'app/components/Link' import { useI18n } from 'app/hooks/useI18n' import { getTableData } from 'app/utils/table' -import { AuthorInfo, DatasetAuthors } from './DatasetAuthors' +import { DatasetAuthors } from './DatasetAuthors' import { DatasetType } from './type' function DatabaseEntryList({ entries }: { entries: string }) { @@ -95,14 +96,11 @@ export function DatasetMetadataTable({ labelExtra: , renderValue: () => { return ( - + ) }, values: [], - className: 'leading-sds-body-xs', + className: 'leading-sds-body-s', }, { diff --git a/frontend/packages/data-portal/app/components/Link/Link.mock.tsx b/frontend/packages/data-portal/app/components/Link/Link.mock.tsx new file mode 100644 index 000000000..abcfc2f98 --- /dev/null +++ b/frontend/packages/data-portal/app/components/Link/Link.mock.tsx @@ -0,0 +1,7 @@ +import { LinkProps } from '@remix-run/react' +import { isString } from 'lodash-es' + +export function MockLinkComponent({ to, ...props }: LinkProps) { + // eslint-disable-next-line jsx-a11y/anchor-has-content + return +} diff --git a/frontend/packages/data-portal/app/components/Link.tsx b/frontend/packages/data-portal/app/components/Link/Link.tsx similarity index 100% rename from frontend/packages/data-portal/app/components/Link.tsx rename to frontend/packages/data-portal/app/components/Link/Link.tsx diff --git a/frontend/packages/data-portal/app/components/Link/index.ts b/frontend/packages/data-portal/app/components/Link/index.ts new file mode 100644 index 000000000..f019a126c --- /dev/null +++ b/frontend/packages/data-portal/app/components/Link/index.ts @@ -0,0 +1,2 @@ +export * from './Link' +export * from './Link.mock' diff --git a/frontend/packages/data-portal/app/components/Run/AnnotationOveriewTable.tsx b/frontend/packages/data-portal/app/components/Run/AnnotationOveriewTable.tsx index 1d3472fc4..702849995 100644 --- a/frontend/packages/data-portal/app/components/Run/AnnotationOveriewTable.tsx +++ b/frontend/packages/data-portal/app/components/Run/AnnotationOveriewTable.tsx @@ -30,10 +30,10 @@ export function AnnotationOverviewTable() { : t('annotationAuthors'), labelExtra: , renderValue: () => { - return + return }, values: [''], - className: 'leading-sds-body-xs', + className: 'leading-sds-body-s', }, { label: t('publication'), diff --git a/frontend/packages/data-portal/app/components/Run/AnnotationTable.tsx b/frontend/packages/data-portal/app/components/Run/AnnotationTable.tsx index 16a022824..fcd4332f1 100644 --- a/frontend/packages/data-portal/app/components/Run/AnnotationTable.tsx +++ b/frontend/packages/data-portal/app/components/Run/AnnotationTable.tsx @@ -185,11 +185,7 @@ export function AnnotationTable() {
- +
), diff --git a/frontend/packages/data-portal/app/components/icons/EnvelopeIcon.tsx b/frontend/packages/data-portal/app/components/icons/EnvelopeIcon.tsx index 5aadea474..2931777ba 100644 --- a/frontend/packages/data-portal/app/components/icons/EnvelopeIcon.tsx +++ b/frontend/packages/data-portal/app/components/icons/EnvelopeIcon.tsx @@ -1,8 +1,11 @@ +import { TestIds } from 'app/constants/testIds' + import { IconProps } from './icon.types' export function EnvelopeIcon(props: IconProps) { return ( /app/$1', + '^(.*).png$': '/app/utils/fileMock.ts', + }, + + transform: { + '^.+\\.tsx?$': ['ts-jest', { useESM: true }], }, } diff --git a/frontend/packages/data-portal/package.json b/frontend/packages/data-portal/package.json index dace56d8b..4c2f4e5d6 100644 --- a/frontend/packages/data-portal/package.json +++ b/frontend/packages/data-portal/package.json @@ -25,7 +25,8 @@ "lint:stylelint": "stylelint 'app/**/*.css'", "lint:stylelint:fix": "pnpm lint:stylelint --fix", "start": "NODE_ENV=production node --loader ts-node/esm server.ts", - "test": "NODE_OPTIONS='--experimental-vm-modules' jest", + "test": "NODE_OPTIONS='--experimental-vm-modules' jest --coverage --config jest.config.cjs", + "test:watch": "NODE_OPTIONS='--experimental-vm-modules' jest --watch --coverage --config jest.config.cjs", "type-check": "tsc -p tsconfig.json --noEmit" }, "dependencies": { @@ -50,6 +51,7 @@ "@remix-run/node": "^2.0.1", "@remix-run/react": "^2.0.1", "@remix-run/server-runtime": "^2.0.1", + "@remix-run/testing": "^2.0.1", "@tanstack/react-table": "^8.10.6", "axios": "^1.6.2", "axios-cache-interceptor": "^1.3.2", @@ -92,15 +94,16 @@ "utility-types": "^3.10.0" }, "devDependencies": { + "@jest/globals": "^29.7.0", "@parcel/watcher": "^2.3.0", "@playwright/test": "^1.41.2", "@remix-run/dev": "^2.0.1", "@tailwindcss/typography": "^0.5.10", - "@testing-library/jest-dom": "^6.1.4", - "@testing-library/react": "^14.0.0", + "@testing-library/jest-dom": "^6.4.5", + "@testing-library/react": "^15.0.7", "@types/compression": "^1.7.3", "@types/express": "^4.17.19", - "@types/jest": "^29.5.5", + "@types/jest": "^29.5.12", "@types/katex": "^0.16.7", "@types/lodash": "^4.14.199", "@types/lodash-es": "^4.17.9", @@ -127,7 +130,7 @@ "stylelint-config-sass-guidelines": "^10.0.0", "stylelint-prettier": "^4.0.2", "tailwindcss": "^3.3.3", - "ts-jest": "^29.1.1", + "ts-jest": "^29.1.2", "typed-css-modules": "^0.8.0", "typescript": "^5.2.2" } diff --git a/frontend/packages/data-portal/tsconfig.json b/frontend/packages/data-portal/tsconfig.json index f1ffa55bc..3960b5958 100644 --- a/frontend/packages/data-portal/tsconfig.json +++ b/frontend/packages/data-portal/tsconfig.json @@ -16,7 +16,8 @@ "skipLibCheck": true, "strict": true, "target": "esnext", - "incremental": true + "incremental": true, + "types": ["@testing-library/jest-dom"] }, "include": ["*.d.ts", "*.ts", "app/**/*.ts", "app/**/*.tsx", "e2e/**/*.ts"], "exclude": ["node_modules"] diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index be45b8090..3d6adcda9 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -80,6 +80,9 @@ importers: '@remix-run/server-runtime': specifier: ^2.0.1 version: 2.0.1(typescript@5.2.2) + '@remix-run/testing': + specifier: ^2.0.1 + version: 2.9.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) '@tanstack/react-table': specifier: ^8.10.6 version: 8.10.6(react-dom@18.2.0)(react@18.2.0) @@ -201,6 +204,9 @@ importers: specifier: ^3.10.0 version: 3.10.0 devDependencies: + '@jest/globals': + specifier: ^29.7.0 + version: 29.7.0 '@parcel/watcher': specifier: ^2.3.0 version: 2.3.0 @@ -214,11 +220,11 @@ importers: specifier: ^0.5.10 version: 0.5.10(tailwindcss@3.3.3) '@testing-library/jest-dom': - specifier: ^6.1.4 - version: 6.1.4(@types/jest@29.5.5)(jest@29.7.0) + specifier: ^6.4.5 + version: 6.4.5(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0) '@testing-library/react': - specifier: ^14.0.0 - version: 14.0.0(react-dom@18.2.0)(react@18.2.0) + specifier: ^15.0.7 + version: 15.0.7(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) '@types/compression': specifier: ^1.7.3 version: 1.7.3 @@ -226,8 +232,8 @@ importers: specifier: ^4.17.19 version: 4.17.19 '@types/jest': - specifier: ^29.5.5 - version: 29.5.5 + specifier: ^29.5.12 + version: 29.5.12 '@types/katex': specifier: ^0.16.7 version: 0.16.7 @@ -307,8 +313,8 @@ importers: specifier: ^3.3.3 version: 3.3.3(ts-node@10.9.1) ts-jest: - specifier: ^29.1.1 - version: 29.1.1(@babel/core@7.23.0)(esbuild@0.17.6)(jest@29.7.0)(typescript@5.2.2) + specifier: ^29.1.2 + version: 29.1.2(@babel/core@7.23.0)(esbuild@0.17.6)(jest@29.7.0)(typescript@5.2.2) typed-css-modules: specifier: ^0.8.0 version: 0.8.0 @@ -379,8 +385,8 @@ packages: resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} engines: {node: '>=0.10.0'} - /@adobe/css-tools@4.3.1: - resolution: {integrity: sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg==} + /@adobe/css-tools@4.3.3: + resolution: {integrity: sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==} dev: true /@alloc/quick-lru@5.2.0: @@ -440,7 +446,7 @@ packages: '@babel/core': 7.23.0 '@babel/generator': 7.23.0 '@babel/parser': 7.23.0 - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 '@babel/traverse': 7.23.0 '@babel/types': 7.23.0 babel-preset-fbjs: 3.4.0(@babel/core@7.23.0) @@ -1096,13 +1102,13 @@ packages: engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.0 + dev: false /@babel/runtime@7.24.0: resolution: {integrity: sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.0 - dev: false /@babel/template@7.22.15: resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} @@ -2882,7 +2888,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 '@mui/utils': 5.14.13(@types/react@18.2.28)(react@18.2.0) '@types/react': 18.2.28 prop-types: 15.8.1 @@ -2902,7 +2908,7 @@ packages: '@emotion/styled': optional: true dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 '@emotion/cache': 11.11.0 '@emotion/react': 11.11.1(@types/react@18.2.28)(react@18.2.0) '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.28)(react@18.2.0) @@ -3610,6 +3616,25 @@ packages: typescript: 5.2.2 dev: false + /@remix-run/node@2.9.1(typescript@5.2.2): + resolution: {integrity: sha512-shicVsSmXepj4zotWHR2kLmyYCxQ25mHmfBL11ODIcIs7iSmQO+W7CNbmX1jcRvhHki/v+S/n4fMm0iKNeJ92w==} + engines: {node: '>=18.0.0'} + peerDependencies: + typescript: ^5.1.0 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@remix-run/server-runtime': 2.9.1(typescript@5.2.2) + '@remix-run/web-fetch': 4.4.2 + '@web3-storage/multipart-parser': 1.0.0 + cookie-signature: 1.2.1 + source-map-support: 0.5.21 + stream-slice: 0.1.2 + typescript: 5.2.2 + undici: 6.16.0 + dev: false + /@remix-run/react@2.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2): resolution: {integrity: sha512-xZgJcRjzx9gjCzh7dDZGQJcmQPPFisMrDwhUuIzlSHuR2rEQCCGZPBLVCpbD1zhDfbdvOugbf2DLSmP2TEBXNA==} engines: {node: '>=18.0.0'} @@ -3629,6 +3654,32 @@ packages: typescript: 5.2.2 dev: false + /@remix-run/react@2.9.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2): + resolution: {integrity: sha512-QQVZPS56okvDF3FBuGBjyKuYa6bXZvXFFlYeWfngI8ZnDbCzQLKV1oD0FWMhKuQxMaKs25uWg2YwGqwWTdin3w==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0.0 + react-dom: ^18.0.0 + typescript: ^5.1.0 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@remix-run/router': 1.16.0 + '@remix-run/server-runtime': 2.9.1(typescript@5.2.2) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-router: 6.23.0(react@18.2.0) + react-router-dom: 6.23.0(react-dom@18.2.0)(react@18.2.0) + turbo-stream: 2.0.1 + typescript: 5.2.2 + dev: false + + /@remix-run/router@1.16.0: + resolution: {integrity: sha512-Quz1KOffeEf/zwkCBM3kBtH4ZoZ+pT3xIXBG4PPW/XFtDP7EGhtTiC2+gpL9GnR7+Qdet5Oa6cYSvwKYg6kN9Q==} + engines: {node: '>=14.0.0'} + dev: false + /@remix-run/router@1.9.0: resolution: {integrity: sha512-bV63itrKBC0zdT27qYm6SDZHlkXwFL1xMBuhkn+X7l0+IIhNaH5wuuvZKp6eKhCD4KFhujhfhCT1YxXW6esUIA==} engines: {node: '>=14.0.0'} @@ -3651,6 +3702,45 @@ packages: type-fest: 4.3.2 typescript: 5.2.2 + /@remix-run/server-runtime@2.9.1(typescript@5.2.2): + resolution: {integrity: sha512-6rRPiR+eMdTPkDojlYiZohVzXkD3+3X55ZvD78axMVocwGcDFFllpmgH9NSR2RKHW9eZDZUfKvNCwd/i9W6Xog==} + engines: {node: '>=18.0.0'} + peerDependencies: + typescript: ^5.1.0 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@remix-run/router': 1.16.0 + '@types/cookie': 0.6.0 + '@web3-storage/multipart-parser': 1.0.0 + cookie: 0.6.0 + set-cookie-parser: 2.6.0 + source-map: 0.7.4 + turbo-stream: 2.0.1 + typescript: 5.2.2 + dev: false + + /@remix-run/testing@2.9.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2): + resolution: {integrity: sha512-BrZYicOtaBm4JBz5DJSUFQ9ym/q4Ii40dgw5GHKAemSoWWzr6QCtPBvaEWUMRqaXiLL1oiXux++aKG7/6nbppQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0.0 + typescript: ^5.1.0 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@remix-run/node': 2.9.1(typescript@5.2.2) + '@remix-run/react': 2.9.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) + '@remix-run/router': 1.16.0 + react: 18.2.0 + react-router-dom: 6.23.0(react-dom@18.2.0)(react@18.2.0) + typescript: 5.2.2 + transitivePeerDependencies: + - react-dom + dev: false + /@remix-run/web-blob@3.1.0: resolution: {integrity: sha512-owGzFLbqPH9PlKb8KvpNJ0NO74HWE2euAn61eEiyCXX/oteoVzTVSN8mpLgDjaxBf2btj5/nUllSUgpyd6IH6g==} dependencies: @@ -3672,6 +3762,20 @@ packages: mrmime: 1.0.1 dev: false + /@remix-run/web-fetch@4.4.2: + resolution: {integrity: sha512-jgKfzA713/4kAW/oZ4bC3MoLWyjModOVDjFPNseVqcJKSafgIscrYL9G50SurEYLswPuoU3HzSbO0jQCMYWHhA==} + engines: {node: ^10.17 || >=12.3} + dependencies: + '@remix-run/web-blob': 3.1.0 + '@remix-run/web-file': 3.1.0 + '@remix-run/web-form-data': 3.1.0 + '@remix-run/web-stream': 1.1.0 + '@web3-storage/multipart-parser': 1.0.0 + abort-controller: 3.0.0 + data-uri-to-buffer: 3.0.1 + mrmime: 1.0.1 + dev: false + /@remix-run/web-file@3.1.0: resolution: {integrity: sha512-dW2MNGwoiEYhlspOAXFBasmLeYshyAyhIdrlXBi06Duex5tDr3ut2LFKVj7tyHLmn8nnNwFf1BjNbkQpygC2aQ==} dependencies: @@ -3739,31 +3843,34 @@ packages: engines: {node: '>=12'} dev: false - /@testing-library/dom@9.3.3: - resolution: {integrity: sha512-fB0R+fa3AUqbLHWyxXa2kGVtf1Fe1ZZFr0Zp6AIbIAzXb2mKbEXl+PCQNUOaq5lbTab5tfctfXRNsWXxa2f7Aw==} - engines: {node: '>=14'} + /@testing-library/dom@10.1.0: + resolution: {integrity: sha512-wdsYKy5zupPyLCW2Je5DLHSxSfbIp6h80WoHOQc+RPtmPGA52O9x5MJEkv92Sjonpq+poOAtUKhh1kBGAXBrNA==} + engines: {node: '>=18'} dependencies: '@babel/code-frame': 7.22.13 - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 '@types/aria-query': 5.0.2 - aria-query: 5.1.3 + aria-query: 5.3.0 chalk: 4.1.2 dom-accessibility-api: 0.5.16 lz-string: 1.5.0 pretty-format: 27.5.1 dev: true - /@testing-library/jest-dom@6.1.4(@types/jest@29.5.5)(jest@29.7.0): - resolution: {integrity: sha512-wpoYrCYwSZ5/AxcrjLxJmCU6I5QAJXslEeSiMQqaWmP2Kzpd1LvF/qxmAIW2qposULGWq2gw30GgVNFLSc2Jnw==} + /@testing-library/jest-dom@6.4.5(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0): + resolution: {integrity: sha512-AguB9yvTXmCnySBP1lWjfNNUwpbElsaQ567lt2VdGqAdHtpieLgjmcVyv1q7PMIvLbgpDdkWV5Ydv3FEejyp2A==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} peerDependencies: '@jest/globals': '>= 28' + '@types/bun': latest '@types/jest': '>= 28' jest: '>= 28' vitest: '>= 0.32' peerDependenciesMeta: '@jest/globals': optional: true + '@types/bun': + optional: true '@types/jest': optional: true jest: @@ -3771,27 +3878,33 @@ packages: vitest: optional: true dependencies: - '@adobe/css-tools': 4.3.1 - '@babel/runtime': 7.23.2 - '@types/jest': 29.5.5 + '@adobe/css-tools': 4.3.3 + '@babel/runtime': 7.24.0 + '@jest/globals': 29.7.0 + '@types/jest': 29.5.12 aria-query: 5.3.0 chalk: 3.0.0 css.escape: 1.5.1 - dom-accessibility-api: 0.5.16 + dom-accessibility-api: 0.6.3 jest: 29.7.0(@types/node@20.8.4)(ts-node@10.9.1) lodash: 4.17.21 redent: 3.0.0 dev: true - /@testing-library/react@14.0.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-S04gSNJbYE30TlIMLTzv6QCTzt9AqIF5y6s6SzVFILNcNvbV/jU96GeiTPillGQo+Ny64M/5PV7klNYYgv5Dfg==} - engines: {node: '>=14'} + /@testing-library/react@15.0.7(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-cg0RvEdD1TIhhkm1IeYMQxrzy0MtUNfa3minv4MjbgcYzJAZ7yD0i0lwoPOTPr+INtiXFezt2o8xMSnyHhEn2Q==} + engines: {node: '>=18'} peerDependencies: + '@types/react': ^18.0.0 react: ^18.0.0 react-dom: ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true dependencies: - '@babel/runtime': 7.23.2 - '@testing-library/dom': 9.3.3 + '@babel/runtime': 7.24.0 + '@testing-library/dom': 10.1.0 + '@types/react': 18.2.28 '@types/react-dom': 18.2.13 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -3882,6 +3995,10 @@ packages: /@types/cookie@0.4.1: resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} + /@types/cookie@0.6.0: + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + dev: false + /@types/debug@4.1.9: resolution: {integrity: sha512-8Hz50m2eoS56ldRlepxSBa6PWEVCtzUo/92HgLc2qTMnotJNIm7xP+UZhyWoYsyOdd5dxZ+NZLb24rsKyFs2ow==} dependencies: @@ -3944,8 +4061,8 @@ packages: '@types/istanbul-lib-report': 3.0.1 dev: true - /@types/jest@29.5.5: - resolution: {integrity: sha512-ebylz2hnsWR9mYvmBFbXJXr+33UPc4+ZdxyDXh5w0FlPBTfCVN3wPL+kuOiQt3xvrK419v7XWeAs+AeOksafXg==} + /@types/jest@29.5.12: + resolution: {integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==} dependencies: expect: 29.7.0 pretty-format: 29.7.0 @@ -4595,12 +4712,6 @@ packages: /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - /aria-query@5.1.3: - resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} - dependencies: - deep-equal: 2.2.2 - dev: true - /aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} dependencies: @@ -4825,7 +4936,7 @@ packages: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 cosmiconfig: 7.1.0 resolve: 1.22.6 dev: false @@ -4991,7 +5102,7 @@ packages: /broadcast-channel@3.7.0: resolution: {integrity: sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 detect-node: 2.1.0 js-sha3: 0.8.0 microseconds: 0.2.0 @@ -5693,29 +5804,6 @@ packages: optional: true dev: true - /deep-equal@2.2.2: - resolution: {integrity: sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA==} - dependencies: - array-buffer-byte-length: 1.0.0 - call-bind: 1.0.2 - es-get-iterator: 1.1.3 - get-intrinsic: 1.2.1 - is-arguments: 1.1.1 - is-array-buffer: 3.0.2 - is-date-object: 1.0.5 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 - isarray: 2.0.5 - object-is: 1.1.5 - object-keys: 1.1.1 - object.assign: 4.1.4 - regexp.prototype.flags: 1.5.1 - side-channel: 1.0.4 - which-boxed-primitive: 1.0.2 - which-collection: 1.0.1 - which-typed-array: 1.1.11 - dev: true - /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -5860,10 +5948,14 @@ packages: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} dev: true + /dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + dev: true + /dom-helpers@5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 csstype: 3.1.2 dev: false @@ -6008,20 +6100,6 @@ packages: unbox-primitive: 1.0.2 which-typed-array: 1.1.11 - /es-get-iterator@1.1.3: - resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 - has-symbols: 1.0.3 - is-arguments: 1.1.1 - is-map: 2.0.2 - is-set: 2.0.2 - is-string: 1.0.7 - isarray: 2.0.5 - stop-iteration-iterator: 1.0.0 - dev: true - /es-iterator-helpers@1.0.15: resolution: {integrity: sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==} dependencies: @@ -7666,6 +7744,7 @@ packages: dependencies: call-bind: 1.0.2 has-tostringtag: 1.0.0 + dev: false /is-array-buffer@3.0.2: resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} @@ -7808,6 +7887,7 @@ packages: /is-map@2.0.2: resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} + dev: false /is-negative-zero@2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} @@ -7871,6 +7951,7 @@ packages: /is-set@2.0.2: resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} + dev: false /is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} @@ -7927,6 +8008,7 @@ packages: /is-weakmap@2.0.1: resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} + dev: false /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} @@ -7938,6 +8020,7 @@ packages: dependencies: call-bind: 1.0.2 get-intrinsic: 1.2.1 + dev: false /is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} @@ -9181,7 +9264,7 @@ packages: /media-query-parser@2.0.2: resolution: {integrity: sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 dev: true /media-typer@0.3.0: @@ -9941,14 +10024,6 @@ packages: /object-inspect@1.12.3: resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} - /object-is@1.1.5: - resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.1 - dev: true - /object-keys@0.4.0: resolution: {integrity: sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==} dev: false @@ -10860,6 +10935,19 @@ packages: react-router: 6.16.0(react@18.2.0) dev: false + /react-router-dom@6.23.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Q9YaSYvubwgbal2c9DJKfx6hTNoBp3iJDsl+Duva/DwxoJH+OTXkxGpql4iUK2sla/8z4RpjAm6EWx1qUDuopQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + dependencies: + '@remix-run/router': 1.16.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-router: 6.23.0(react@18.2.0) + dev: false + /react-router@6.16.0(react@18.2.0): resolution: {integrity: sha512-VT4Mmc4jj5YyjpOi5jOf0I+TYzGpvzERy4ckNSvSh2RArv8LLoCxlsZ2D+tc7zgjxcY34oTz2hZaeX5RVprKqA==} engines: {node: '>=14.0.0'} @@ -10870,6 +10958,16 @@ packages: react: 18.2.0 dev: false + /react-router@6.23.0(react@18.2.0): + resolution: {integrity: sha512-wPMZ8S2TuPadH0sF5irFGjkNLIcRvOSaEe7v+JER8508dyJumm6XZB1u5kztlX0RVq6AzRVndzqcUh6sFIauzA==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + dependencies: + '@remix-run/router': 1.16.0 + react: 18.2.0 + dev: false + /react-transition-group@4.4.5(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} peerDependencies: @@ -11008,7 +11106,7 @@ packages: /relay-runtime@12.0.0: resolution: {integrity: sha512-QU6JKr1tMsry22DXNy9Whsq5rmvwr3LSZiiWV/9+DFpuTWvp+WFhobWMc8TC4OjKFfNhEZy7mOiqUAn5atQtug==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 fbjs: 3.0.5 invariant: 2.2.4 transitivePeerDependencies: @@ -11542,13 +11640,6 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} - /stop-iteration-iterator@1.0.0: - resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} - engines: {node: '>= 0.4'} - dependencies: - internal-slot: 1.0.5 - dev: true - /stream-shift@1.0.1: resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} dev: true @@ -12136,9 +12227,9 @@ packages: tslib: 2.6.2 dev: false - /ts-jest@29.1.1(@babel/core@7.23.0)(esbuild@0.17.6)(jest@29.7.0)(typescript@5.2.2): - resolution: {integrity: sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + /ts-jest@29.1.2(@babel/core@7.23.0)(esbuild@0.17.6)(jest@29.7.0)(typescript@5.2.2): + resolution: {integrity: sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==} + engines: {node: ^16.10.0 || ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@babel/core': '>=7.0.0-beta.0 <8' @@ -12247,6 +12338,10 @@ packages: tslib: 1.14.1 typescript: 5.2.2 + /turbo-stream@2.0.1: + resolution: {integrity: sha512-sm0ZtcX9YWh28p5X8t5McxC2uthrt9p+g0bGE0KTVFhnhNWefpSVCr+67zRNDUOfo4bpXwiOp7otO+dyQ7/y/A==} + dev: false + /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -12365,6 +12460,11 @@ packages: /undici-types@5.25.3: resolution: {integrity: sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==} + /undici@6.16.0: + resolution: {integrity: sha512-HQfVddOTb5PJtfLnJ1Px8bNGyIg/z7WTj1hjUSna1Itsv59Oca9JdclIU08ToNqvWWXjFLRzc9rqjnpfw5UWcQ==} + engines: {node: '>=18.17'} + dev: false + /unified@10.1.2: resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} dependencies: @@ -12489,7 +12589,7 @@ packages: /unload@2.2.0: resolution: {integrity: sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 detect-node: 2.1.0 dev: false @@ -12817,6 +12917,7 @@ packages: is-set: 2.0.2 is-weakmap: 2.0.1 is-weakset: 2.0.2 + dev: false /which-module@2.0.1: resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}