diff --git a/.ebextensions/autoscaling.config b/.ebextensions/autoscaling.config new file mode 100644 index 00000000..a44295cd --- /dev/null +++ b/.ebextensions/autoscaling.config @@ -0,0 +1,6 @@ +Resources: + AWSEBAutoScalingGroup: + Type: "AWS::AutoScaling::AutoScalingGroup" + Properties: + HealthCheckType: ELB + HealthCheckGracePeriod: 300 \ No newline at end of file diff --git a/.platform/confighooks/predeploy/00_build.sh b/.platform/confighooks/predeploy/00_build.sh index 8ceacc1a..0068a45c 100755 --- a/.platform/confighooks/predeploy/00_build.sh +++ b/.platform/confighooks/predeploy/00_build.sh @@ -4,4 +4,4 @@ echo primsa migrate npm run migrate echo build with npm -npm run build \ No newline at end of file +sudo -E -u webapp npm run build \ No newline at end of file diff --git a/.platform/hooks/predeploy/00_build.sh b/.platform/hooks/predeploy/00_build.sh index 8ceacc1a..0068a45c 100755 --- a/.platform/hooks/predeploy/00_build.sh +++ b/.platform/hooks/predeploy/00_build.sh @@ -4,4 +4,4 @@ echo primsa migrate npm run migrate echo build with npm -npm run build \ No newline at end of file +sudo -E -u webapp npm run build \ No newline at end of file diff --git a/.platform/nginx/nginx.conf b/.platform/nginx/nginx.conf index 56b39d96..4faf5adf 100644 --- a/.platform/nginx/nginx.conf +++ b/.platform/nginx/nginx.conf @@ -28,9 +28,9 @@ http { listen 8008 default_server; access_log /var/log/nginx/access.log main; - client_header_timeout 60; - client_body_timeout 60; - keepalive_timeout 60; + client_header_timeout 90; + client_body_timeout 90; + keepalive_timeout 90; gzip on; gzip_comp_level 4; gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript; diff --git a/Dockerfile b/Dockerfile index a2b59949..5425a3ad 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -FROM node:16.16.0-bullseye +FROM node:18.17.0-bullseye ENV NODE_ENV=development diff --git a/api/resolvers/rewards.js b/api/resolvers/rewards.js index bb4d3aa7..f7e6fdd4 100644 --- a/api/resolvers/rewards.js +++ b/api/resolvers/rewards.js @@ -12,6 +12,8 @@ export default { } }) + if (!lastReward) return { total: 0, sources: [] } + const [result] = await models.$queryRaw` SELECT coalesce(FLOOR(sum(sats)), 0) as total, json_build_array( json_build_object('name', 'donations', 'value', coalesce(FLOOR(sum(sats) FILTER(WHERE type = 'DONATION')), 0)), diff --git a/api/resolvers/serial.js b/api/resolvers/serial.js index 5edd2c2e..9971a3b9 100644 --- a/api/resolvers/serial.js +++ b/api/resolvers/serial.js @@ -35,17 +35,17 @@ async function serialize (models, ...calls) { if (error.message.includes('SN_REVOKED_OR_EXHAUSTED')) { bail(new Error('faucet has been revoked or is exhausted')) } - if (error.message.includes('23514')) { - bail(new Error('constraint failure')) - } if (error.message.includes('SN_INV_PENDING_LIMIT')) { bail(new Error('too many pending invoices')) } if (error.message.includes('SN_INV_EXCEED_BALANCE')) { bail(new Error('pending invoices must not cause balance to exceed 1m sats')) } - if (error.message.includes('40001')) { - throw new Error('wallet balance serialization failure - retry again') + if (error.message.includes('40001') || error.code === 'P2034') { + throw new Error('wallet balance serialization failure - try again') + } + if (error.message.includes('23514') || ['P2002', 'P2003', 'P2004'].includes(error.code)) { + bail(new Error('constraint failure')) } bail(error) } diff --git a/api/resolvers/wallet.js b/api/resolvers/wallet.js index 08d716bd..c32845da 100644 --- a/api/resolvers/wallet.js +++ b/api/resolvers/wallet.js @@ -172,7 +172,7 @@ export default { } switch (f.type) { case 'withdrawal': - f.msats = (-1 * f.msats) - f.msatsFee + f.msats = (-1 * Number(f.msats)) - Number(f.msatsFee) break case 'spent': f.msats *= -1 diff --git a/api/ssrApollo.js b/api/ssrApollo.js index 1341f47d..26aa5d94 100644 --- a/api/ssrApollo.js +++ b/api/ssrApollo.js @@ -38,14 +38,14 @@ export default async function getSSRApolloClient ({ req, res, me = null }) { assumeImmutableResults: true, defaultOptions: { watchQuery: { - fetchPolicy: 'cache-only', - nextFetchPolicy: 'cache-only', + fetchPolicy: 'no-cache', + nextFetchPolicy: 'no-cache', canonizeResults: true, ssr: true }, query: { - fetchPolicy: 'cache-first', - nextFetchPolicy: 'cache-only', + fetchPolicy: 'no-cache', + nextFetchPolicy: 'no-cache', canonizeResults: true, ssr: true } diff --git a/components/charts.js b/components/charts.js index aa586d0d..d1a10561 100644 --- a/components/charts.js +++ b/components/charts.js @@ -89,7 +89,7 @@ export function WhenAreaChart ({ data }) { tick={{ fill: 'var(--theme-grey)' }} /> - + {Object.keys(data[0]).filter(v => v !== 'time' && v !== '__typename').map((v, i) => )} @@ -124,7 +124,7 @@ export function WhenLineChart ({ data }) { tick={{ fill: 'var(--theme-grey)' }} /> - + {Object.keys(data[0]).filter(v => v !== 'time' && v !== '__typename').map((v, i) => )} @@ -160,7 +160,7 @@ export function WhenComposedChart ({ data, lineNames, areaNames, barNames }) { /> - + {barNames?.map((v, i) => )} diff --git a/components/comment.js b/components/comment.js index dd9e033f..a016ca97 100644 --- a/components/comment.js +++ b/components/comment.js @@ -114,15 +114,19 @@ export default function Comment ({ if (Number(router.query.commentId) === Number(item.id)) { // HACK wait for other comments to collapse if they're collapsed setTimeout(() => { - ref.current.scrollIntoView() - ref.current.classList.add('flash-it') - router.replace({ - pathname: router.pathname, - query: { id: router.query.id } - }, undefined, { scroll: false }) + ref.current.scrollIntoView({ behavior: 'instant', block: 'start' }) + ref.current.classList.add('outline-it') }, 20) } - }, [item]) + }, [item.id, router.query.commentId]) + + useEffect(() => { + if (router.query.commentsViewedAt && + me?.id !== item.user?.id && + new Date(item.createdAt).getTime() > router.query.commentsViewedAt) { + ref.current.classList.add('outline-new-comment') + } + }, [item.id]) const bottomedOut = depth === COMMENT_DEPTH_LIMIT const op = root.user.name === item.user.name @@ -131,6 +135,8 @@ export default function Comment ({ return (
ref.current.classList.add('outline-new-comment-unset')} + onTouchStart={() => ref.current.classList.add('outline-new-comment-unset')} >
{item.meDontLike diff --git a/components/comments.js b/components/comments.js index dfc3c2da..d8a22455 100644 --- a/components/comments.js +++ b/components/comments.js @@ -73,7 +73,7 @@ export default function Comments ({ parentId, pinned, bio, parentCreatedAt, comm router.push({ pathname: router.pathname, query: { ...router.query, sort } - }, router.asPath, { scroll: false }) + }, undefined, { scroll: false }) }} /> : null} diff --git a/components/dark-mode.js b/components/dark-mode.js index fe6e97f0..e540dd24 100644 --- a/components/dark-mode.js +++ b/components/dark-mode.js @@ -1,5 +1,54 @@ import { useEffect, useState } from 'react' -import { getTheme, listenForThemeChange, setTheme } from '../public/dark' + +const handleThemeChange = (dark) => { + const root = window.document.documentElement + root.setAttribute('data-bs-theme', dark ? 'dark' : 'light') +} + +const STORAGE_KEY = 'darkMode' +const PREFER_DARK_QUERY = '(prefers-color-scheme: dark)' + +const getTheme = () => { + const mql = window.matchMedia(PREFER_DARK_QUERY) + const supportsColorSchemeQuery = mql.media === PREFER_DARK_QUERY + let localStorageTheme = null + try { + localStorageTheme = window.localStorage.getItem(STORAGE_KEY) + } catch (err) {} + const localStorageExists = localStorageTheme !== null + if (localStorageExists) { + localStorageTheme = JSON.parse(localStorageTheme) + } + + if (localStorageExists) { + return { user: true, dark: localStorageTheme } + } else if (supportsColorSchemeQuery) { + return { user: false, dark: mql.matches } + } +} + +const setTheme = (dark) => { + window.localStorage.setItem(STORAGE_KEY, JSON.stringify(dark)) + handleThemeChange(dark) +} + +const listenForThemeChange = (onChange) => { + const mql = window.matchMedia(PREFER_DARK_QUERY) + mql.onchange = mql => { + const { user, dark } = getTheme() + if (!user) { + handleThemeChange(dark) + onChange({ user, dark }) + } + } + window.onstorage = e => { + if (e.key === STORAGE_KEY) { + const dark = JSON.parse(e.newValue) + setTheme(dark) + onChange({ user: true, dark }) + } + } +} export default function useDarkMode () { const [dark, setDark] = useState() diff --git a/components/fee-button.js b/components/fee-button.js index f6daeac1..5aa4aed3 100644 --- a/components/fee-button.js +++ b/components/fee-button.js @@ -5,7 +5,7 @@ import styles from './fee-button.module.css' import { gql, useQuery } from '@apollo/client' import { useFormikContext } from 'formik' import { useMe } from './me' -import { ANON_COMMENT_FEE, ANON_POST_FEE } from '../lib/constants' +import { SSR, ANON_COMMENT_FEE, ANON_POST_FEE } from '../lib/constants' import { useEffect } from 'react' function Receipt ({ cost, repetition, hasImgLink, baseFee, parentId, boost }) { @@ -48,7 +48,7 @@ export default function FeeButton ({ parentId, hasImgLink, baseFee, ChildButton, const query = parentId ? gql`{ itemRepetition(parentId: "${parentId}") }` : gql`{ itemRepetition }` - const { data } = useQuery(query, { pollInterval: 1000, nextFetchPolicy: 'cache-and-network' }) + const { data } = useQuery(query, SSR ? {} : { pollInterval: 1000, nextFetchPolicy: 'cache-and-network' }) const repetition = me ? data?.itemRepetition || 0 : 0 const formik = useFormikContext() const boost = Number(formik?.values?.boost) || 0 diff --git a/components/fee-button.module.css b/components/fee-button.module.css index 87c27ed9..c2d40c54 100644 --- a/components/fee-button.module.css +++ b/components/fee-button.module.css @@ -8,6 +8,8 @@ .receipt td { padding: .25rem .1rem; + background-color: var(--theme-inputBg); + color: var(--bs-body-color); } .receipt tfoot { diff --git a/components/footer-rewards.js b/components/footer-rewards.js index ea81b920..51862cf5 100644 --- a/components/footer-rewards.js +++ b/components/footer-rewards.js @@ -1,6 +1,7 @@ import { gql, useQuery } from '@apollo/client' import Link from 'next/link' import { RewardLine } from '../pages/rewards' +import { SSR } from '../lib/constants' const REWARDS = gql` { @@ -10,7 +11,7 @@ const REWARDS = gql` }` export default function Rewards () { - const { data } = useQuery(REWARDS, { pollInterval: 60000, nextFetchPolicy: 'cache-and-network' }) + const { data } = useQuery(REWARDS, SSR ? { ssr: false } : { pollInterval: 60000, nextFetchPolicy: 'cache-and-network' }) const total = data?.expectedRewards?.total return ( diff --git a/components/footer.module.css b/components/footer.module.css index 21cda2fa..8cfa5174 100644 --- a/components/footer.module.css +++ b/components/footer.module.css @@ -11,13 +11,13 @@ } .contrastLink { - color: var(--theme-color); + color: var(--bs-body-color); } .contrastLink:hover { - color: var(--theme-color); + color: var(--bs-body-color); } .contrastLink svg { - fill: var(--theme-color); + fill: var(--bs-body-color); } .version { diff --git a/components/form.js b/components/form.js index 093671cd..ee481a4f 100644 --- a/components/form.js +++ b/components/form.js @@ -72,7 +72,7 @@ export function InputSkeleton ({ label, hint }) { return ( {label && {label}} -
+
.
{hint && {hint} @@ -431,7 +431,7 @@ export function Checkbox ({ children, label, groupClassName, hiddenLabel, extra, handleChange && handleChange(e.target.checked, helpers.setValue) }} /> - +
{label}
{extra &&
diff --git a/components/header.js b/components/header.js index 6ed6a115..7525f656 100644 --- a/components/header.js +++ b/components/header.js @@ -10,7 +10,7 @@ import Price from './price' import { useMe } from './me' import Head from 'next/head' import { signOut } from 'next-auth/react' -import { useCallback, useEffect, useState } from 'react' +import { useCallback, useEffect } from 'react' import { randInRange } from '../lib/rand' import { abbrNum } from '../lib/format' import NoteIcon from '../svgs/notification-4-fill.svg' @@ -20,7 +20,7 @@ import CowboyHat from './cowboy-hat' import { Select } from './form' import SearchIcon from '../svgs/search-line.svg' import BackArrow from '../svgs/arrow-left-line.svg' -import { SUBS } from '../lib/constants' +import { SSR, SUBS } from '../lib/constants' import { useLightning } from './lightning' import { HAS_NOTIFICATIONS } from '../fragments/notifications' @@ -31,24 +31,28 @@ function WalletSummary ({ me }) { function Back () { const router = useRouter() - const [show, setShow] = useState() - useEffect(() => { - setShow(typeof window !== 'undefined' && router.asPath !== '/' && - (typeof window.navigation === 'undefined' || window.navigation.canGoBack === undefined || window?.navigation.canGoBack)) - }, [router.asPath]) - - if (show) { - return router.back()}> - } - return null + return router.asPath !== '/' && + { + if (typeof window.navigation === 'undefined' || window.navigation.canGoBack === undefined || window?.navigation.canGoBack) { + router.back() + } else { + router.push('/') + } + }} + > + + } function NotificationBell () { - const { data } = useQuery(HAS_NOTIFICATIONS, { - pollInterval: 30000, - nextFetchPolicy: 'cache-and-network' - }) + const { data } = useQuery(HAS_NOTIFICATIONS, SSR + ? {} + : { + pollInterval: 30000, + nextFetchPolicy: 'cache-and-network' + }) return ( <> diff --git a/components/header.module.css b/components/header.module.css index 407edaa8..a5340c94 100644 --- a/components/header.module.css +++ b/components/header.module.css @@ -38,7 +38,7 @@ background-color: var(--bs-primary); top: 3px; right: 0px; - border: 1px solid var(--theme-body); + border: 1px solid var(--bs-body-bg); } .notification { @@ -47,7 +47,7 @@ background-color: var(--bs-danger); top: 1px; right: 8px; - border: 1px solid var(--theme-body); + border: 1px solid var(--bs-body-bg); } .navbarNav { diff --git a/components/item-info.js b/components/item-info.js index 8f0970f4..0d3063fd 100644 --- a/components/item-info.js +++ b/components/item-info.js @@ -5,7 +5,7 @@ import Badge from 'react-bootstrap/Badge' import Dropdown from 'react-bootstrap/Dropdown' import Countdown from './countdown' import { abbrNum } from '../lib/format' -import { newComments } from '../lib/new-comments' +import { newComments, commentsViewedAt } from '../lib/new-comments' import { timeSince } from '../lib/time' import CowboyHat from './cowboy-hat' import { DeleteDropdownItem } from './delete' @@ -48,9 +48,22 @@ export default function ItemInfo ({ item, pendingSats, full, commentsText, class {abbrNum(item.boost)} boost \ } - + { + const viewedAt = commentsViewedAt(item) + if (viewedAt) { + e.preventDefault() + router.push( + `/items/${item.id}?commentsViewedAt=${viewedAt}`, + `/items/${item.id}`) + } + }} title={`${item.commentSats} sats`} className='text-reset position-relative' + > {item.ncomments} {commentsText || 'comments'} - {hasNewComments && <>{' '}new} + {hasNewComments && + + {' '} + } \ diff --git a/components/item-job.js b/components/item-job.js index 6df76d9d..b3cbb546 100644 --- a/components/item-job.js +++ b/components/item-job.js @@ -54,7 +54,7 @@ export default function ItemJob ({ item, toc, rank, children }) { @{item.user.name} - + {timeSince(new Date(item.createdAt))} diff --git a/components/item.js b/components/item.js index 691b2859..d63444bc 100644 --- a/components/item.js +++ b/components/item.js @@ -12,6 +12,8 @@ import Flag from '../svgs/flag-fill.svg' import ImageIcon from '../svgs/image-fill.svg' import { abbrNum } from '../lib/format' import ItemInfo from './item-info' +import { commentsViewedAt } from '../lib/new-comments' +import { useRouter } from 'next/router' export function SearchTitle ({ title }) { return reactStringReplace(title, /:high\[([^\]]+)\]/g, (match, i) => { @@ -21,6 +23,7 @@ export function SearchTitle ({ title }) { export default function Item ({ item, rank, belowTitle, right, full, children, siblingComments }) { const titleRef = useRef() + const router = useRouter() const [pendingSats, setPendingSats] = useState(0) const image = item.url && item.url.startsWith(process.env.NEXT_PUBLIC_IMGPROXY_URL) @@ -39,7 +42,18 @@ export default function Item ({ item, rank, belowTitle, right, full, children, s : item.meDontLike ? : }
- + { + const viewedAt = commentsViewedAt(item) + if (viewedAt) { + e.preventDefault() + router.push( + `/items/${item.id}?commentsViewedAt=${viewedAt}`, + `/items/${item.id}`) + } + }} ref={titleRef} className={`${styles.title} text-reset me-2`} + > {item.searchTitle ? : item.title} {item.pollCost && } {item.bounty > 0 && diff --git a/components/item.module.css b/components/item.module.css index d90d2692..bdbcbffb 100644 --- a/components/item.module.css +++ b/components/item.module.css @@ -7,6 +7,15 @@ padding-bottom: .15rem; } +.notification { + position: absolute; + padding: 3px; + background-color: var(--bs-info); + top: -3px; + right: -4px; + border: 1px solid var(--bs-body-bg); +} + .icon { display: inline-block; } diff --git a/components/items.js b/components/items.js index 7a7a38b2..547b2986 100644 --- a/components/items.js +++ b/components/items.js @@ -8,19 +8,21 @@ import { CommentFlat } from './comment' import { SUB_ITEMS } from '../fragments/subs' import { LIMIT } from '../lib/cursor' import ItemFull from './item-full' +import { useData } from './use-data' export default function Items ({ ssrData, variables = {}, query, destructureData, rank, noMoreText, Footer, filter = () => true }) { const { data, fetchMore } = useQuery(query || SUB_ITEMS, { variables }) const Foooter = Footer || MoreFooter + const dat = useData(data, ssrData) const { items, pins, cursor } = useMemo(() => { - if (!data && !ssrData) return {} + if (!dat) return {} if (destructureData) { - return destructureData(data || ssrData) + return destructureData(dat) } else { - return data?.items || ssrData?.items + return dat?.items } - }, [data, ssrData]) + }, [dat]) const pinMap = useMemo(() => pins?.reduce((a, p) => { a[p.position] = p; return a }, {}), [pins]) @@ -28,7 +30,7 @@ export default function Items ({ ssrData, variables = {}, query, destructureData const Skeleton = useCallback(() => , [rank, items]) - if (!ssrData && !data) { + if (!dat) { return } diff --git a/components/lightning-auth.js b/components/lightning-auth.js index dbb1860e..8cb07e47 100644 --- a/components/lightning-auth.js +++ b/components/lightning-auth.js @@ -9,6 +9,7 @@ import Qr, { QrSkeleton } from './qr' import styles from './lightning-auth.module.css' import BackIcon from '../svgs/arrow-left-line.svg' import { useRouter } from 'next/router' +import { SSR } from '../lib/constants' function QrAuth ({ k1, encodedUrl, slashtagUrl, callbackUrl }) { const query = gql` @@ -18,7 +19,7 @@ function QrAuth ({ k1, encodedUrl, slashtagUrl, callbackUrl }) { k1 } }` - const { data } = useQuery(query, { pollInterval: 1000, nextFetchPolicy: 'cache-and-network' }) + const { data } = useQuery(query, SSR ? {} : { pollInterval: 1000, nextFetchPolicy: 'cache-and-network' }) useEffect(() => { if (data?.lnAuth?.pubkey) { diff --git a/components/login.js b/components/login.js index 1d9fd5b7..bd85815d 100644 --- a/components/login.js +++ b/components/login.js @@ -43,7 +43,7 @@ const authErrorMessages = { default: 'Auth failed. Try again or choose a different method.' } -export function authErrorMessage(error) { +export function authErrorMessage (error) { return error && (authErrorMessages[error] ?? authErrorMessages.default) } @@ -85,10 +85,13 @@ export default function Login ({ providers, callbackUrl, error, text, Header, Fo className={`mt-2 ${styles.providerButton}`} key={provider.id} type={provider.id.toLowerCase()} - onClick={() => router.push({ - pathname: router.pathname, - query: { callbackUrl: router.query.callbackUrl, type: provider.name.toLowerCase() } - })} + onClick={() => { + const { nodata, ...query } = router.query + router.push({ + pathname: router.pathname, + query: { ...query, type: provider.name.toLowerCase() } + }) + }} text={`${text || 'Login'} with`} /> ) diff --git a/components/me.js b/components/me.js index be5360ef..4b9b4121 100644 --- a/components/me.js +++ b/components/me.js @@ -1,13 +1,14 @@ import React, { useContext } from 'react' import { useQuery } from '@apollo/client' import { ME } from '../fragments/users' +import { SSR } from '../lib/constants' export const MeContext = React.createContext({ me: null }) export function MeProvider ({ me, children }) { - const { data } = useQuery(ME, { pollInterval: 1000, nextFetchPolicy: 'cache-and-network' }) + const { data } = useQuery(ME, SSR ? {} : { pollInterval: 1000, nextFetchPolicy: 'cache-and-network' }) const contextValue = { me: data?.me || me diff --git a/components/notifications.js b/components/notifications.js index 7e264492..37484712 100644 --- a/components/notifications.js +++ b/components/notifications.js @@ -1,9 +1,9 @@ import { useState, useEffect, useMemo } from 'react' -import { useApolloClient, useQuery } from '@apollo/client' +import { useQuery } from '@apollo/client' import Comment, { CommentSkeleton } from './comment' import Item from './item' import ItemJob from './item-job' -import { HAS_NOTIFICATIONS, NOTIFICATIONS } from '../fragments/notifications' +import { NOTIFICATIONS } from '../fragments/notifications' import MoreFooter from './more-footer' import Invite from './invite' import { ignoreClick } from '../lib/clicks' @@ -20,29 +20,47 @@ import styles from './notifications.module.css' import { useServiceWorker } from './serviceworker' import { Checkbox, Form } from './form' import { useRouter } from 'next/router' +import { useData } from './use-data' -function Notification ({ n }) { - switch (n.__typename) { - case 'Earn': return - case 'Invitification': return - case 'InvoicePaid': return - case 'Referral': return - case 'Streak': return - case 'Votification': return - case 'Mention': return - case 'JobChanged': return - case 'Reply': return - } - console.error('__typename not supported:', n.__typename) - return null +function Notification ({ n, fresh }) { + const type = n.__typename + + return ( + + { + (type === 'Earn' && ) || + (type === 'Invitification' && ) || + (type === 'InvoicePaid' && ) || + (type === 'Referral' && ) || + (type === 'Streak' && ) || + (type === 'Votification' && ) || + (type === 'Mention' && ) || + (type === 'JobChanged' && ) || + (type === 'Reply' && ) + } + + ) } -function NotificationLayout ({ children, href, as }) { +function NotificationLayout ({ children, nid, href, as, fresh }) { const router = useRouter() + if (!href) return
{children}
return (
!ignoreClick(e) && router.push(href, as)} + className={ + `clickToContext ${fresh ? styles.fresh : ''} ${router?.query?.nid === nid ? 'outline-it' : ''}` + } + onClick={async (e) => { + if (ignoreClick(e)) return + nid && await router.replace({ + pathname: router.pathname, + query: { + ...router.query, + nid + } + }, router.asPath, { ...router.options, shallow: true }) + router.push(href, as) + }} > {children}
@@ -50,6 +68,14 @@ function NotificationLayout ({ children, href, as }) { } const defaultOnClick = n => { + const type = n.__typename + if (type === 'Earn') return {} + if (type === 'Invitification') return { href: '/invites' } + if (type === 'InvoicePaid') return { href: `/invoices/${n.invoice.id}` } + if (type === 'Referral') return { href: '/referrals/month' } + if (type === 'Streak') return {} + + // Votification, Mention, JobChanged, Reply all have item if (!n.item.title) { const path = n.item.path.split('.') if (path.length > COMMENT_DEPTH_LIMIT + 1) { @@ -126,7 +152,7 @@ function EarnNotification ({ n }) {
- you stacked {n.earnedSats} sats in rewards{timeSince(new Date(n.sortTime))} + you stacked {n.earnedSats} sats in rewards{timeSince(new Date(n.sortTime))}
{n.sources &&
@@ -145,7 +171,7 @@ function EarnNotification ({ n }) { function Invitification ({ n }) { return ( - + <> your invite has been redeemed by {n.invite.invitees.length} stackers @@ -157,35 +183,31 @@ function Invitification ({ n }) { } />
- + ) } function InvoicePaid ({ n }) { return ( - -
- {n.earnedSats} sats were deposited in your account - {timeSince(new Date(n.sortTime))} -
-
+
+ {n.earnedSats} sats were deposited in your account + {timeSince(new Date(n.sortTime))} +
) } function Referral ({ n }) { return ( - - - someone joined via one of your referral links - {timeSince(new Date(n.sortTime))} - - + + someone joined via one of your referral links + {timeSince(new Date(n.sortTime))} + ) } function Votification ({ n }) { return ( - + <> your {n.item.title ? 'post' : 'reply'} {n.item.fwdUser ? 'forwarded' : 'stacked'} {n.earnedSats} sats{n.item.fwdUser && ` to @${n.item.fwdUser.name}`} @@ -200,13 +222,13 @@ function Votification ({ n }) {
)}
- + ) } function Mention ({ n }) { return ( - + <> you were mentioned in @@ -220,13 +242,13 @@ function Mention ({ n }) {
)}
- + ) } function JobChanged ({ n }) { return ( - + <> {n.item.status === 'ACTIVE' ? 'your job is active again' @@ -235,29 +257,27 @@ function JobChanged ({ n }) { : 'your job has been stopped')} - + ) } function Reply ({ n }) { return ( - -
- {n.item.title - ? - : ( -
- - - -
- )} -
-
+
+ {n.item.title + ? + : ( +
+ + + +
+ )} +
) } -function NotificationAlert () { +export function NotificationAlert () { const [showAlert, setShowAlert] = useState(false) const [hasSubscription, setHasSubscription] = useState(false) const [error, setError] = useState(null) @@ -316,47 +336,39 @@ function NotificationAlert () { ) } +const nid = n => n.__typename + n.id + n.sortTime + export default function Notifications ({ ssrData }) { const { data, fetchMore } = useQuery(NOTIFICATIONS) - const client = useApolloClient() + const router = useRouter() + const dat = useData(data, ssrData) + + const { notifications: { notifications, lastChecked, cursor } } = useMemo(() => { + return dat || { notifications: {} } + }, [dat]) useEffect(() => { - client.writeQuery({ - query: HAS_NOTIFICATIONS, - data: { - hasNewNotes: false - } - }) - }, [client]) + if (lastChecked && !router?.query?.checkedAt) { + router.replace({ + pathname: router.pathname, + query: { + ...router.query, + nodata: true, // make sure nodata is set so we don't fetch on back/forward + checkedAt: lastChecked + } + }, router.asPath, { ...router.options, shallow: true }) + } + }, [router, lastChecked]) - const { notifications: { notifications, earn, lastChecked, cursor } } = useMemo(() => { - if (!data && !ssrData) return { notifications: {} } - return data || ssrData - }, [data, ssrData]) - - const [fresh, old] = useMemo(() => { - if (!notifications) return [[], []] - return notifications.reduce((result, n) => { - result[new Date(n.sortTime).getTime() > lastChecked ? 0 : 1].push(n) - return result - }, - [[], []]) - }, [notifications, lastChecked]) - - if (!data && !ssrData) return + if (!dat) return return ( <> - -
- {earn && } - {fresh.map((n, i) => ( - - ))} -
- {old.map((n, i) => ( - - ))} + {notifications.map(n => + new Date(router?.query?.checkedAt)} + />)} ) diff --git a/components/notifications.module.css b/components/notifications.module.css index 61705ff4..600ae419 100644 --- a/components/notifications.module.css +++ b/components/notifications.module.css @@ -1,16 +1,16 @@ -.clickToContext { - border-radius: .4rem; - padding: .2rem 0; - cursor: pointer; -} - -.clickToContext:hover { - background-color: rgba(0, 0, 0, 0.03); -} - .fresh { - background-color: rgba(0, 0, 0, 0.03); - border-radius: .4rem; + background-color: rgba(128, 128, 128, 0.1); + border-radius: 0; +} + +.fresh:not(.fresh ~ .fresh) { + border-top-left-radius: .4rem; + border-top-right-radius: .4rem; +} + +.fresh:has(+ :not(.fresh)) { + border-bottom-left-radius: .4rem; + border-bottom-right-radius: .4rem; } .alertBtn { diff --git a/components/price.js b/components/price.js index 15bd7d49..4a36494c 100644 --- a/components/price.js +++ b/components/price.js @@ -4,6 +4,7 @@ import { fixedDecimal } from '../lib/format' import { useMe } from './me' import { PRICE } from '../fragments/price' import { CURRENCY_SYMBOLS } from '../lib/currency' +import { SSR } from '../lib/constants' export const PriceContext = React.createContext({ price: null, @@ -19,8 +20,12 @@ export function PriceProvider ({ price, children }) { const fiatCurrency = me?.fiatCurrency const { data } = useQuery(PRICE, { variables: { fiatCurrency }, - pollInterval: 30000, - nextFetchPolicy: 'cache-and-network' + ...(SSR + ? {} + : { + pollInterval: 30000, + nextFetchPolicy: 'cache-and-network' + }) }) const contextValue = { diff --git a/components/search.module.css b/components/search.module.css index e180a5fd..011061e2 100644 --- a/components/search.module.css +++ b/components/search.module.css @@ -16,7 +16,7 @@ .searchSection.solid { pointer-events: auto; - background: var(--theme-body); + background: var(--bs-body-bg); box-shadow: 0 -4px 12px hsl(0deg 0% 59% / 10%); } diff --git a/components/top-header.js b/components/top-header.js index d176a5ec..57af1b1f 100644 --- a/components/top-header.js +++ b/components/top-header.js @@ -32,7 +32,7 @@ export default function TopHeader ({ sub, cat }) { } const what = cat - const by = router.query.by || '' + const by = router.query.by || (what === 'stackers' ? 'stacked' : 'votes') const when = router.query.when || '' return ( diff --git a/components/upvote.module.css b/components/upvote.module.css index 62387f72..cc38402e 100644 --- a/components/upvote.module.css +++ b/components/upvote.module.css @@ -27,7 +27,7 @@ } .cover { - background: var(--theme-body); + background: var(--bs-body-bg); width: 100%; overflow: hidden; mix-blend-mode: color; diff --git a/components/use-data.js b/components/use-data.js new file mode 100644 index 00000000..9ac52f6d --- /dev/null +++ b/components/use-data.js @@ -0,0 +1,27 @@ +import { useEffect, useRef, useState } from 'react' + +/* + What we want is to use ssrData if it exists, until cache data changes + ... this prevents item list jitter where the intially rendered items + are stale until the cache is rewritten with incoming ssrData +*/ +export function useData (data, ssrData) { + // when fresh is true, it means data has been updated after the initial render and it's populated + const [fresh, setFresh] = useState(false) + + // on first render, we want to use ssrData if it's available + // it's only unavailable on back/forward navigation + const ref = useRef(true) + const firstRender = ref.current + ref.current = false + + useEffect(() => { + if (!firstRender && !fresh && data) setFresh(true) + }, [data]) + + // if we don't have data yet, use ssrData + // if we have data, but it's not fresh, use ssrData + // unless we don't have ssrData + if (!data || (!fresh && ssrData)) return ssrData + return data +} diff --git a/components/user-list.js b/components/user-list.js index 582da750..effca4db 100644 --- a/components/user-list.js +++ b/components/user-list.js @@ -7,6 +7,7 @@ import userStyles from './user-header.module.css' import { useEffect, useMemo, useState } from 'react' import { useQuery } from '@apollo/client' import MoreFooter from './more-footer' +import { useData } from './use-data' // all of this nonsense is to show the stat we are sorting by first const Stacked = ({ user }) => ({abbrNum(user.stacked)} stacked) @@ -37,26 +38,25 @@ function seperate (arr, seperator) { export default function UserList ({ ssrData, query, variables, destructureData }) { const { data, fetchMore } = useQuery(query, { variables }) + const dat = useData(data, ssrData) const [statComps, setStatComps] = useState(seperate(STAT_COMPONENTS, Seperator)) useEffect(() => { - if (variables?.by) { - // shift the stat we are sorting by to the front - const comps = [...STAT_COMPONENTS] - setStatComps(seperate([...comps.splice(STAT_POS[variables.by], 1), ...comps], Seperator)) - } + // shift the stat we are sorting by to the front + const comps = [...STAT_COMPONENTS] + setStatComps(seperate([...comps.splice(STAT_POS[variables.by || 0], 1), ...comps], Seperator)) }, [variables?.by]) const { users, cursor } = useMemo(() => { - if (!data && !ssrData) return {} + if (!dat) return {} if (destructureData) { - return destructureData(data || ssrData) + return destructureData(dat) } else { - return data || ssrData + return dat } - }, [data, ssrData]) + }, [dat]) - if (!ssrData && !data) { + if (!dat) { return } diff --git a/lib/apollo.js b/lib/apollo.js index 382ce427..23b5be99 100644 --- a/lib/apollo.js +++ b/lib/apollo.js @@ -1,5 +1,6 @@ import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client' import { decodeCursor, LIMIT } from './cursor' +import { SSR } from './constants' function isFirstPage (cursor, existingThings) { if (cursor) { @@ -12,7 +13,6 @@ function isFirstPage (cursor, existingThings) { } } -const SSR = typeof window === 'undefined' const defaultFetchPolicy = SSR ? 'cache-only' : 'cache-first' const defaultNextFetchPolicy = SSR ? 'cache-only' : 'cache-first' @@ -158,14 +158,18 @@ function getClient (uri) { assumeImmutableResults: true, defaultOptions: { watchQuery: { + initialFetchPolicy: defaultFetchPolicy, fetchPolicy: defaultFetchPolicy, nextFetchPolicy: defaultNextFetchPolicy, - canonizeResults: true + canonizeResults: true, + ssr: SSR }, query: { + initialFetchPolicy: defaultFetchPolicy, fetchPolicy: defaultFetchPolicy, nextFetchPolicy: defaultNextFetchPolicy, - canonizeResults: true + canonizeResults: true, + ssr: SSR } } }) diff --git a/lib/constants.js b/lib/constants.js index 467c492d..ffc7a4f3 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -45,3 +45,6 @@ module.exports = { ANON_POST_FEE: 1000, ANON_COMMENT_FEE: 100, } + +export const OLD_ITEM_DAYS = 3 +export const SSR = typeof window === 'undefined' diff --git a/lib/new-comments.js b/lib/new-comments.js index 1742879a..20ae8dd4 100644 --- a/lib/new-comments.js +++ b/lib/new-comments.js @@ -14,13 +14,17 @@ export function commentsViewedAfterComment (rootId, createdAt) { window.localStorage.setItem(`${COMMENTS_NUM_PREFIX}:${rootId}`, existingRootComments + 1) } +export function commentsViewedAt (item) { + return window.localStorage.getItem(`${COMMENTS_VIEW_PREFIX}:${item.id}`) +} + export function newComments (item) { if (!item.parentId) { - const commentsViewedAt = window.localStorage.getItem(`${COMMENTS_VIEW_PREFIX}:${item.id}`) - const commentsViewNum = window.localStorage.getItem(`${COMMENTS_NUM_PREFIX}:${item.id}`) + const viewedAt = commentsViewedAt(item) + const viewNum = window.localStorage.getItem(`${COMMENTS_NUM_PREFIX}:${item.id}`) - if (commentsViewedAt && commentsViewNum) { - return commentsViewedAt < new Date(item.lastCommentAt).getTime() || commentsViewNum < item.ncomments + if (viewedAt && viewNum) { + return viewedAt < new Date(item.lastCommentAt).getTime() || viewNum < item.ncomments } } diff --git a/lib/prisma-adapter.js b/lib/prisma-adapter.js deleted file mode 100644 index 442533f3..00000000 --- a/lib/prisma-adapter.js +++ /dev/null @@ -1,296 +0,0 @@ -/* eslint-disable */ -'use strict' - -Object.defineProperty(exports, '__esModule', { - value: true -}) -exports.getCompoundId = getCompoundId -exports.Adapter = exports.PrismaLegacyAdapter = PrismaLegacyAdapter - -const _crypto = require('crypto') - -function getCompoundId (a, b) { - return (0, _crypto.createHash)('sha256').update(`${a}:${b}`).digest('hex') -} - -function PrismaLegacyAdapter (config) { - const { - prisma, - modelMapping = { - User: 'user', - Account: 'account', - Session: 'session', - VerificationRequest: 'verificationRequest' - } - } = config - const { - User, - Account, - Session, - VerificationRequest - } = modelMapping - return { - async getAdapter ({ - session: { - maxAge, - updateAge - }, - secret, - ...appOptions - }) { - const sessionMaxAge = maxAge * 1000 - const sessionUpdateAge = updateAge * 1000 - - const hashToken = token => (0, _crypto.createHash)('sha256').update(`${token}${secret}`).digest('hex') - - return { - displayName: 'PRISMA_LEGACY', - - createUser (profile) { - let _profile$emailVerifie - - return prisma[User].create({ - data: { - name: profile.name, - email: profile.email, - image: profile.image, - emailVerified: (_profile$emailVerifie = profile.emailVerified) === null || _profile$emailVerifie === void 0 ? void 0 : _profile$emailVerifie.toISOString() - } - }) - }, - - getUser (id) { - return prisma[User].findUnique({ - where: { - id: Number(id) - } - }) - }, - - getUserByEmail (email) { - if (email) { - return prisma[User].findUnique({ - where: { - email - } - }) - } - - return null - }, - - async getUserByProviderAccountId (providerId, providerAccountId) { - const account = await prisma[Account].findUnique({ - where: { - compoundId: getCompoundId(providerId, providerAccountId) - } - }) - - if (account) { - return prisma[User].findUnique({ - where: { - id: account.userId - } - }) - } - - return null - }, - - updateUser (user) { - const { - id, - name, - email, - image, - emailVerified - } = user - return prisma[User].update({ - where: { - id - }, - data: { - name, - email, - image, - emailVerified: emailVerified === null || emailVerified === void 0 ? void 0 : emailVerified.toISOString() - } - }) - }, - - deleteUser (userId) { - return prisma[User].delete({ - where: { - id: userId - } - }) - }, - - linkAccount (userId, providerId, providerType, providerAccountId, refreshToken, accessToken, accessTokenExpires) { - return prisma[Account].create({ - data: { - accessToken, - refreshToken, - compoundId: getCompoundId(providerId, providerAccountId), - providerAccountId: `${providerAccountId}`, - providerId, - providerType, - accessTokenExpires, - userId - } - }) - }, - - unlinkAccount (_, providerId, providerAccountId) { - return prisma[Account].delete({ - where: { - compoundId: getCompoundId(providerId, providerAccountId) - } - }) - }, - - createSession (user) { - let expires = null - - if (sessionMaxAge) { - const dateExpires = new Date() - dateExpires.setTime(dateExpires.getTime() + sessionMaxAge) - expires = dateExpires.toISOString() - } - - return prisma[Session].create({ - data: { - expires, - userId: user.id, - sessionToken: (0, _crypto.randomBytes)(32).toString('hex'), - accessToken: (0, _crypto.randomBytes)(32).toString('hex') - } - }) - }, - - async getSession (sessionToken) { - const session = await prisma[Session].findUnique({ - where: { - sessionToken - } - }) - - if (session !== null && session !== void 0 && session.expires && new Date() > session.expires) { - await prisma[Session].delete({ - where: { - sessionToken - } - }) - return null - } - - return session - }, - - updateSession (session, force) { - if (sessionMaxAge && (sessionUpdateAge || sessionUpdateAge === 0) && session.expires) { - const dateSessionIsDueToBeUpdated = new Date(session.expires) - dateSessionIsDueToBeUpdated.setTime(dateSessionIsDueToBeUpdated.getTime() - sessionMaxAge) - dateSessionIsDueToBeUpdated.setTime(dateSessionIsDueToBeUpdated.getTime() + sessionUpdateAge) - - if (new Date() > dateSessionIsDueToBeUpdated) { - const newExpiryDate = new Date() - newExpiryDate.setTime(newExpiryDate.getTime() + sessionMaxAge) - session.expires = newExpiryDate - } else if (!force) { - return null - } - } else { - if (!force) { - return null - } - } - - const { - id, - expires - } = session - return prisma[Session].update({ - where: { - id - }, - data: { - expires: expires.toISOString() - } - }) - }, - - deleteSession (sessionToken) { - return prisma[Session].delete({ - where: { - sessionToken - } - }) - }, - - async createVerificationRequest (identifier, url, token, _, provider) { - const { - sendVerificationRequest, - maxAge - } = provider - let expires = null - - if (maxAge) { - const dateExpires = new Date() - dateExpires.setTime(dateExpires.getTime() + maxAge * 1000) - expires = dateExpires.toISOString() - } - - const verificationRequest = await prisma[VerificationRequest].create({ - data: { - identifier, - token: hashToken(token), - expires - } - }) - await sendVerificationRequest({ - identifier, - url, - token, - baseUrl: appOptions.baseUrl, - provider - }) - return verificationRequest - }, - - async getVerificationRequest (identifier, token) { - const hashedToken = hashToken(token) - const verificationRequest = await prisma[VerificationRequest].findFirst({ - where: { - identifier, - token: hashedToken - } - }) - - if (verificationRequest && verificationRequest.expires && new Date() > verificationRequest.expires) { - await prisma[VerificationRequest].deleteMany({ - where: { - identifier, - token: hashedToken - } - }) - return null - } - - return verificationRequest - }, - - async deleteVerificationRequest (identifier, token) { - await prisma[VerificationRequest].deleteMany({ - where: { - identifier, - token: hashToken(token) - } - }) - } - - } - } - - } -} diff --git a/next.config.js b/next.config.js index 4c39c7ce..84ee04e5 100644 --- a/next.config.js +++ b/next.config.js @@ -40,12 +40,6 @@ module.exports = withPlausibleProxy()({ source: '/_next/:asset*', headers: corsHeaders }, - { - source: '/dark.js', - headers: [ - ...corsHeaders - ] - }, { source: '/.well-known/:slug*', headers: [ @@ -120,6 +114,10 @@ module.exports = withPlausibleProxy()({ source: '/.well-known/web-app-origin-association', destination: '/api/web-app-origin-association' }, + { + source: '/~:sub/:slug*\\?:query*', + destination: '/~/:slug*?:query*&sub=:sub' + }, { source: '/~:sub/:slug*', destination: '/~/:slug*?sub=:sub' diff --git a/package-lock.json b/package-lock.json index 04595f0c..e8bdb320 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.0", "dependencies": { "@apollo/client": "^3.7.17", - "@apollo/server": "^4.8.1", + "@apollo/server": "^4.9.0", "@as-integrations/next": "^2.0.1", "@auth/prisma-adapter": "^1.0.1", "@graphql-tools/schema": "^10.0.0", @@ -21,12 +21,11 @@ "acorn": "^8.10.0", "ajv": "^8.12.0", "async-retry": "^1.3.1", - "aws-sdk": "^2.1422.0", + "aws-sdk": "^2.1425.0", "babel-plugin-inline-react-svg": "^2.0.2", "bech32": "^2.0.0", "bolt11": "^1.4.1", - "bootstrap": "^5.3.0", - "browserslist": "^4.21.4", + "bootstrap": "^5.3.1", "canonical-json": "0.0.4", "clipboard-copy": "^4.0.1", "cross-fetch": "^4.0.0", @@ -44,18 +43,19 @@ "mdast-util-gfm": "^3.0.0", "mdast-util-to-string": "^4.0.0", "micromark-extension-gfm": "^3.0.0", - "next": "^13.4.12", + "next": "^13.4.13-canary.12", "next-auth": "^4.22.3", "next-plausible": "^3.10.1", "next-seo": "^6.1.0", - "nextjs-progressbar": "0.0.16", "node-s3-url-encode": "^0.0.4", "nodemailer": "^6.9.4", "nostr": "^0.2.8", + "nprogress": "^0.2.0", "opentimestamps": "^0.4.9", "page-metadata-parser": "^1.1.4", "pageres": "^7.1.0", "pg-boss": "^9.0.3", + "prisma": "^5.0.0", "qrcode.react": "^3.1.0", "react": "^18.2.0", "react-avatar-editor": "^13.0.0", @@ -74,11 +74,11 @@ "remark-gfm": "^3.0.1", "remove-markdown": "^0.5.0", "sass": "^1.64.1", - "tldts": "^6.0.12", + "tldts": "^6.0.13", "typescript": "^5.1.6", "unist-util-visit": "^5.0.0", "url-unshort": "^6.1.0", - "web-push": "^3.6.2", + "web-push": "^3.6.4", "webln": "^0.3.2", "webpack": "^5.88.2", "workbox-navigation-preload": "^7.0.0", @@ -94,12 +94,11 @@ "@babel/core": "^7.22.9", "@babel/eslint-parser": "^7.22.9", "@next/eslint-plugin-next": "^13.4.12", - "eslint": "^8.45.0", - "prisma": "^5.0.0", + "eslint": "^8.46.0", "standard": "^17.1.0" }, "engines": { - "node": "18.16.1" + "node": "18.17.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -189,9 +188,9 @@ } }, "node_modules/@apollo/server": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/@apollo/server/-/server-4.8.1.tgz", - "integrity": "sha512-gHDYfWXNdo8B6z4z7qs4KLscX7HCFtpG6k744H+y+8IixjNzyGPcSlR+e0CZr42tRjPfi5z0UtHRr6dpTSh+5A==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@apollo/server/-/server-4.9.0.tgz", + "integrity": "sha512-ca1tO5no7PC402ArVP2qDhjpwnZm0ThpEJTfrKoY62mzPaKH0tLjy7Mt909QGyLziwf6c15Q+V+hQYVZKdcUrw==", "dependencies": { "@apollo/cache-control-types": "^1.0.3", "@apollo/server-gateway-interface": "^1.1.1", @@ -501,17 +500,6 @@ } } }, - "node_modules/@auth/core/node_modules/preact-render-to-string": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz", - "integrity": "sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==", - "dependencies": { - "pretty-format": "^3.8.0" - }, - "peerDependencies": { - "preact": ">=10" - } - }, "node_modules/@auth/prisma-adapter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@auth/prisma-adapter/-/prisma-adapter-1.0.1.tgz", @@ -2268,9 +2256,9 @@ } }, "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", + "integrity": "sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2289,9 +2277,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", - "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.1.tgz", + "integrity": "sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -2361,9 +2349,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", - "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.46.0.tgz", + "integrity": "sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2725,9 +2713,9 @@ } }, "node_modules/@next/env": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.12.tgz", - "integrity": "sha512-RmHanbV21saP/6OEPBJ7yJMuys68cIf8OBBWd7+uj40LdpmswVAwe1uzeuFyUsd6SfeITWT3XnQfn6wULeKwDQ==" + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.13-canary.12.tgz", + "integrity": "sha512-57VwH93IMUnzmtAGIyqkI5DvPoyBnrc4c6pfa5QFuayFy3/0z62Oya5PrzI2NoQzcUxLzR5bmtA92z1iJAtELw==" }, "node_modules/@next/eslint-plugin-next": { "version": "13.4.12", @@ -2739,9 +2727,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.12.tgz", - "integrity": "sha512-deUrbCXTMZ6ZhbOoloqecnUeNpUOupi8SE2tx4jPfNS9uyUR9zK4iXBvH65opVcA/9F5I/p8vDXSYbUlbmBjZg==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.13-canary.12.tgz", + "integrity": "sha512-iGST7H/wQar5WMC4AE1XIfHnHdZs90gcq0pKVI+pAianQfR0ALJL0Qtjd4exSRm1qNnsdZKpu9qszUvOVzrisg==", "cpu": [ "arm64" ], @@ -2754,9 +2742,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.12.tgz", - "integrity": "sha512-WRvH7RxgRHlC1yb5oG0ZLx8F7uci9AivM5/HGGv9ZyG2Als8Ij64GC3d+mQ5sJhWjusyU6T6V1WKTUoTmOB0zQ==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.13-canary.12.tgz", + "integrity": "sha512-xVIlo21twTkdXgYzR219zPIyJ6sitxT8e/jnSmssD2QRLLwipu9jGH7ROZlTaDrwIEphLo+02JkCbnBpz+O+zg==", "cpu": [ "x64" ], @@ -2769,9 +2757,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.12.tgz", - "integrity": "sha512-YEKracAWuxp54tKiAvvq73PUs9lok57cc8meYRibTWe/VdPB2vLgkTVWFcw31YDuRXdEhdX0fWS6Q+ESBhnEig==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.13-canary.12.tgz", + "integrity": "sha512-ajXugsgKYn4KngC/m+DYi5m8aVLcLabFM0Wkw1dM9MxHYjBAbIxcZzWIyfEk3aGWZGc2MOeWpoxykGDhNFhpOA==", "cpu": [ "arm64" ], @@ -2784,9 +2772,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.12.tgz", - "integrity": "sha512-LhJR7/RAjdHJ2Isl2pgc/JaoxNk0KtBgkVpiDJPVExVWA1c6gzY57+3zWuxuyWzTG+fhLZo2Y80pLXgIJv7g3g==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.13-canary.12.tgz", + "integrity": "sha512-MDeShMtg26cHjP8NdeUsbXcvZWBtObox3OuL2g/+8yz7u0irEM8heMiOyBHyTn2IXAQM2Mb5bWVcujJ490cY4g==", "cpu": [ "arm64" ], @@ -2799,9 +2787,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.12.tgz", - "integrity": "sha512-1DWLL/B9nBNiQRng+1aqs3OaZcxC16Nf+mOnpcrZZSdyKHek3WQh6j/fkbukObgNGwmCoVevLUa/p3UFTTqgqg==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.13-canary.12.tgz", + "integrity": "sha512-3wn9FTeK0ibhY3YaS9AHv/u2MeyRIbHrywYgdPWRgDut1xIGgj4JlzsPGST/UWLoMZDUCj8gh4RK5ahjp1V3QQ==", "cpu": [ "x64" ], @@ -2814,9 +2802,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.12.tgz", - "integrity": "sha512-kEAJmgYFhp0VL+eRWmUkVxLVunn7oL9Mdue/FS8yzRBVj7Z0AnIrHpTIeIUl1bbdQq1VaoOztnKicAjfkLTRCQ==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.13-canary.12.tgz", + "integrity": "sha512-HpHYIizHkGoEckN+XlcLZ42ojXpVNVrD7V+qFiXEBzSALzP5jc9y6Pj9u/dccAlq68regbSJvAFY04ZVfnA2SQ==", "cpu": [ "x64" ], @@ -2829,9 +2817,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.12.tgz", - "integrity": "sha512-GMLuL/loR6yIIRTnPRY6UGbLL9MBdw2anxkOnANxvLvsml4F0HNIgvnU3Ej4BjbqMTNjD4hcPFdlEow4XHPdZA==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.13-canary.12.tgz", + "integrity": "sha512-SjVHvLMuGE9IaJyGxcxnPcJ/CE8EQoZ2Td3hfgGpzOdOu1hs+HOjv9ipUG33JG5A4PBzoQ1VY3d81LfdOTfZFw==", "cpu": [ "arm64" ], @@ -2844,9 +2832,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.12.tgz", - "integrity": "sha512-PhgNqN2Vnkm7XaMdRmmX0ZSwZXQAtamBVSa9A/V1dfKQCV1rjIZeiy/dbBnVYGdj63ANfsOR/30XpxP71W0eww==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.13-canary.12.tgz", + "integrity": "sha512-LIYmXkE+dMoYBoqU2HR0vVVUp927P4O5ohk4kR6d2tviNKpX7CPk0MQF+YWNlFrOJco4PTN22WBYhPhYSmPXcA==", "cpu": [ "ia32" ], @@ -2859,9 +2847,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.12.tgz", - "integrity": "sha512-Z+56e/Ljt0bUs+T+jPjhFyxYBcdY2RIq9ELFU+qAMQMteHo7ymbV7CKmlcX59RI9C4YzN8PgMgLyAoi916b5HA==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.13-canary.12.tgz", + "integrity": "sha512-tnNDC+EIBmow2Y3pGXyIvQDhECSC8PwXgRflQnczwnWWNNLMq5fzy45gYLw/85NSqkQ6NvEz9B9+UGzAx3kW5Q==", "cpu": [ "x64" ], @@ -3017,7 +3005,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.0.0.tgz", "integrity": "sha512-kyT/8fd0OpWmhAU5YnY7eP31brW1q1YrTGoblWrhQJDiN/1K+Z8S1kylcmtjqx5wsUGcP1HBWutayA/jtyt+sg==", - "dev": true, "hasInstallScript": true }, "node_modules/@prisma/engines-version": { @@ -3159,9 +3146,9 @@ } }, "node_modules/@restart/ui/node_modules/uncontrollable": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.2.tgz", - "integrity": "sha512-/GDx+K1STGtpgTsj5Dj3J51YaKxZDblbCQHTH1zHLuoBEWodj6MjtRVv3TUijj1JYLRLSFsFzN8NV4M3QV4d9w==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", "peerDependencies": { "react": ">=16.14.0" } @@ -3687,11 +3674,6 @@ "node": ">= 6" } }, - "node_modules/@types/nprogress": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@types/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha512-1cYJrqq9GezNFPsWTZpFut/d4CjpZqA0vhqDUPFWYKF1oIyBz5qnoYMzR+0C/T96t3ebLAC1SSnwrVOm5/j74A==" - }, "node_modules/@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -4362,9 +4344,9 @@ } }, "node_modules/aws-sdk": { - "version": "2.1422.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1422.0.tgz", - "integrity": "sha512-dBHCT42s2NOrZVSeKQ+I0kPsAPN0QhbKv05gQFQL79yGIOqLZawWos8vtKSYdp9wEOpiIRttB7m6usYJObKpWA==", + "version": "2.1425.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1425.0.tgz", + "integrity": "sha512-DbY5z7E8RsrX8/0pMBKMuh/rWFic3AghtU2AWkUdzxDi0cUSK7rOSPS/OIURU9Rh0jaNXoA0ujBDdx/CC5CvRA==", "dependencies": { "buffer": "4.9.2", "events": "1.1.1", @@ -4858,9 +4840,9 @@ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, "node_modules/bootstrap": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.0.tgz", - "integrity": "sha512-UnBV3E3v4STVNQdms6jSGO2CvOkjUMdDAVR2V5N4uCMdaIkaQjbcEAMqRimDHIs4uqBYzDAKCQwCB+97tJgHQw==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.1.tgz", + "integrity": "sha512-jzwza3Yagduci2x0rr9MeFSORjcHpt0lRZukZPZQJT1Dth5qzV7XcgGqYzi39KGAVYR8QEDVoO0ubFKOxzMG+g==", "funding": [ { "type": "github", @@ -4872,7 +4854,7 @@ } ], "peerDependencies": { - "@popperjs/core": "^2.11.7" + "@popperjs/core": "^2.11.8" } }, "node_modules/brace-expansion": { @@ -5226,9 +5208,9 @@ } }, "node_modules/capture-website/node_modules/node-fetch": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz", - "integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", @@ -6654,27 +6636,27 @@ } }, "node_modules/eslint": { - "version": "8.45.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", - "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.46.0.tgz", + "integrity": "sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.1.0", - "@eslint/js": "8.44.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.1", + "@eslint/js": "^8.46.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.6.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.2", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -7134,9 +7116,9 @@ } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.1.tgz", - "integrity": "sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -7150,9 +7132,9 @@ } }, "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", + "integrity": "sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -7245,9 +7227,9 @@ } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", + "integrity": "sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -11404,13 +11386,14 @@ } }, "node_modules/mdast-util-to-markdown": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.3.0.tgz", - "integrity": "sha512-6tUSs4r+KK4JGTTiQ7FfHmVOaDrLQJPmpjD6wPMlHGUVXoG9Vjc3jIeP+uyBWRf8clwB2blM+W7+KrlMYQnftA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz", + "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==", "dependencies": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^3.0.0", "mdast-util-to-string": "^3.0.0", "micromark-util-decode-string": "^1.0.0", "unist-util-visit": "^4.0.0", @@ -11421,6 +11404,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-to-markdown/node_modules/mdast-util-phrasing": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz", + "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-to-markdown/node_modules/mdast-util-to-string": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", @@ -13506,11 +13502,11 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node_modules/next": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/next/-/next-13.4.12.tgz", - "integrity": "sha512-eHfnru9x6NRmTMcjQp6Nz0J4XH9OubmzOa7CkWL+AUrUxpibub3vWwttjduu9No16dug1kq04hiUUpo7J3m3Xw==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/next/-/next-13.4.13-canary.12.tgz", + "integrity": "sha512-HVtCufObzWNAPyHpElMEU4b/C7jbmJLS6Xp8to0WFuPwhKVCfmYTO/S9O6nmuflHC+TR9yfh6HGRZ8N9RM8g/g==", "dependencies": { - "@next/env": "13.4.12", + "@next/env": "13.4.13-canary.12", "@swc/helpers": "0.5.1", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -13526,19 +13522,18 @@ "node": ">=16.8.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "13.4.12", - "@next/swc-darwin-x64": "13.4.12", - "@next/swc-linux-arm64-gnu": "13.4.12", - "@next/swc-linux-arm64-musl": "13.4.12", - "@next/swc-linux-x64-gnu": "13.4.12", - "@next/swc-linux-x64-musl": "13.4.12", - "@next/swc-win32-arm64-msvc": "13.4.12", - "@next/swc-win32-ia32-msvc": "13.4.12", - "@next/swc-win32-x64-msvc": "13.4.12" + "@next/swc-darwin-arm64": "13.4.13-canary.12", + "@next/swc-darwin-x64": "13.4.13-canary.12", + "@next/swc-linux-arm64-gnu": "13.4.13-canary.12", + "@next/swc-linux-arm64-musl": "13.4.13-canary.12", + "@next/swc-linux-x64-gnu": "13.4.13-canary.12", + "@next/swc-linux-x64-musl": "13.4.13-canary.12", + "@next/swc-win32-arm64-msvc": "13.4.13-canary.12", + "@next/swc-win32-ia32-msvc": "13.4.13-canary.12", + "@next/swc-win32-x64-msvc": "13.4.13-canary.12" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", - "fibers": ">= 3.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", "sass": "^1.3.0" @@ -13547,9 +13542,6 @@ "@opentelemetry/api": { "optional": true }, - "fibers": { - "optional": true - }, "sass": { "optional": true } @@ -13605,20 +13597,6 @@ "react-dom": ">=16.0.0" } }, - "node_modules/nextjs-progressbar": { - "version": "0.0.16", - "resolved": "https://registry.npmjs.org/nextjs-progressbar/-/nextjs-progressbar-0.0.16.tgz", - "integrity": "sha512-GV0fD38EMD3vSDCmkq+tObmoup6QA91a6a9MxGuhJZuRk/9TNsrHGnIQQQ/sggkMkXuT4fBgF6jRjFwScDT3zA==", - "dependencies": { - "@types/nprogress": "^0.2.0", - "nprogress": "^0.2.0", - "prop-types": "^15.8.1" - }, - "peerDependencies": { - "next": ">= 6.0.0", - "react": ">= 16.0.0" - } - }, "node_modules/noble-secp256k1": { "version": "1.2.14", "resolved": "https://registry.npmjs.org/noble-secp256k1/-/noble-secp256k1-1.2.14.tgz", @@ -14790,9 +14768,9 @@ } }, "node_modules/preact-render-to-string": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz", - "integrity": "sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz", + "integrity": "sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==", "dependencies": { "pretty-format": "^3.8.0" }, @@ -14837,7 +14815,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.0.0.tgz", "integrity": "sha512-KYWk83Fhi1FH59jSpavAYTt2eoMVW9YKgu8ci0kuUnt6Dup5Qy47pcB4/TLmiPAbhGrxxSz7gsSnJcCmkyPANA==", - "dev": true, "hasInstallScript": true, "dependencies": { "@prisma/engines": "5.0.0" @@ -17936,11 +17913,11 @@ "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, "node_modules/tldts": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.0.12.tgz", - "integrity": "sha512-a3xVdMF9FgBqOR6bo51jA90cE0PyKiGIN/L0F8bOJOgMHJ+CujbNDnT3YSYlr/Kod4DJA5ihfJD5tiByx6njgg==", + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.0.13.tgz", + "integrity": "sha512-9v+ZsSU8yBywX6RjT6/pNmwPzTVIeIi7sEiaFDhgsbXZRtvKKrWSiP4K0NTLm1rEvlfKYM24wxxcq7wMr4JRDA==", "dependencies": { - "tldts-core": "^6.0.12" + "tldts-core": "^6.0.13" }, "bin": { "tldts": "bin/cli.js" @@ -17960,9 +17937,9 @@ } }, "node_modules/tldts/node_modules/tldts-core": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.0.12.tgz", - "integrity": "sha512-TYHGh0SJ+MUE0tg5LeDyNMmilUU8VD7fi+o74RGl3xwnakzCjpTFVTn8DHWiDJQmfG768ldqRPSQrvTP6CPjpg==" + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.0.13.tgz", + "integrity": "sha512-LcXhi9dyMeMBTMhpOSUUG4QwiMSADkcdmTg59rXkQyxoWTnyXgvpzoqJGvrhWTDwcs2NseybtqDTA6TWZgNxOA==" }, "node_modules/to-fast-properties": { "version": "2.0.0", @@ -18971,9 +18948,9 @@ } }, "node_modules/web-push": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/web-push/-/web-push-3.6.3.tgz", - "integrity": "sha512-3RlA0lRmLcwlHCRR94Tz+Fw6wPtm0lFm8oyukQunlEIarANxE84Ox9XBgF4+jNlXgO40DIwblOiC43oR46helA==", + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/web-push/-/web-push-3.6.4.tgz", + "integrity": "sha512-An4nhiYuCPJkD51hXid7OIO3TACJsSUhj6XWDNvCDiLCS5ucEkhPUnh/s+jOWAJUUDASGHkuU8hFHg+mX+4vLQ==", "dependencies": { "asn1.js": "^5.3.0", "http_ece": "1.1.0", @@ -19700,9 +19677,9 @@ } }, "@apollo/server": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/@apollo/server/-/server-4.8.1.tgz", - "integrity": "sha512-gHDYfWXNdo8B6z4z7qs4KLscX7HCFtpG6k744H+y+8IixjNzyGPcSlR+e0CZr42tRjPfi5z0UtHRr6dpTSh+5A==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@apollo/server/-/server-4.9.0.tgz", + "integrity": "sha512-ca1tO5no7PC402ArVP2qDhjpwnZm0ThpEJTfrKoY62mzPaKH0tLjy7Mt909QGyLziwf6c15Q+V+hQYVZKdcUrw==", "requires": { "@apollo/cache-control-types": "^1.0.3", "@apollo/server-gateway-interface": "^1.1.1", @@ -19915,16 +19892,6 @@ "oauth4webapi": "^2.0.6", "preact": "10.11.3", "preact-render-to-string": "5.2.3" - }, - "dependencies": { - "preact-render-to-string": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz", - "integrity": "sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==", - "requires": { - "pretty-format": "^3.8.0" - } - } } }, "@auth/prisma-adapter": { @@ -21130,9 +21097,9 @@ }, "dependencies": { "eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", + "integrity": "sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==", "dev": true } } @@ -21144,9 +21111,9 @@ "dev": true }, "@eslint/eslintrc": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", - "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.1.tgz", + "integrity": "sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -21196,9 +21163,9 @@ } }, "@eslint/js": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", - "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.46.0.tgz", + "integrity": "sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA==", "dev": true }, "@fastify/ajv-compiler": { @@ -21498,9 +21465,9 @@ } }, "@next/env": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.12.tgz", - "integrity": "sha512-RmHanbV21saP/6OEPBJ7yJMuys68cIf8OBBWd7+uj40LdpmswVAwe1uzeuFyUsd6SfeITWT3XnQfn6wULeKwDQ==" + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.13-canary.12.tgz", + "integrity": "sha512-57VwH93IMUnzmtAGIyqkI5DvPoyBnrc4c6pfa5QFuayFy3/0z62Oya5PrzI2NoQzcUxLzR5bmtA92z1iJAtELw==" }, "@next/eslint-plugin-next": { "version": "13.4.12", @@ -21512,57 +21479,57 @@ } }, "@next/swc-darwin-arm64": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.12.tgz", - "integrity": "sha512-deUrbCXTMZ6ZhbOoloqecnUeNpUOupi8SE2tx4jPfNS9uyUR9zK4iXBvH65opVcA/9F5I/p8vDXSYbUlbmBjZg==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.13-canary.12.tgz", + "integrity": "sha512-iGST7H/wQar5WMC4AE1XIfHnHdZs90gcq0pKVI+pAianQfR0ALJL0Qtjd4exSRm1qNnsdZKpu9qszUvOVzrisg==", "optional": true }, "@next/swc-darwin-x64": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.12.tgz", - "integrity": "sha512-WRvH7RxgRHlC1yb5oG0ZLx8F7uci9AivM5/HGGv9ZyG2Als8Ij64GC3d+mQ5sJhWjusyU6T6V1WKTUoTmOB0zQ==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.13-canary.12.tgz", + "integrity": "sha512-xVIlo21twTkdXgYzR219zPIyJ6sitxT8e/jnSmssD2QRLLwipu9jGH7ROZlTaDrwIEphLo+02JkCbnBpz+O+zg==", "optional": true }, "@next/swc-linux-arm64-gnu": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.12.tgz", - "integrity": "sha512-YEKracAWuxp54tKiAvvq73PUs9lok57cc8meYRibTWe/VdPB2vLgkTVWFcw31YDuRXdEhdX0fWS6Q+ESBhnEig==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.13-canary.12.tgz", + "integrity": "sha512-ajXugsgKYn4KngC/m+DYi5m8aVLcLabFM0Wkw1dM9MxHYjBAbIxcZzWIyfEk3aGWZGc2MOeWpoxykGDhNFhpOA==", "optional": true }, "@next/swc-linux-arm64-musl": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.12.tgz", - "integrity": "sha512-LhJR7/RAjdHJ2Isl2pgc/JaoxNk0KtBgkVpiDJPVExVWA1c6gzY57+3zWuxuyWzTG+fhLZo2Y80pLXgIJv7g3g==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.13-canary.12.tgz", + "integrity": "sha512-MDeShMtg26cHjP8NdeUsbXcvZWBtObox3OuL2g/+8yz7u0irEM8heMiOyBHyTn2IXAQM2Mb5bWVcujJ490cY4g==", "optional": true }, "@next/swc-linux-x64-gnu": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.12.tgz", - "integrity": "sha512-1DWLL/B9nBNiQRng+1aqs3OaZcxC16Nf+mOnpcrZZSdyKHek3WQh6j/fkbukObgNGwmCoVevLUa/p3UFTTqgqg==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.13-canary.12.tgz", + "integrity": "sha512-3wn9FTeK0ibhY3YaS9AHv/u2MeyRIbHrywYgdPWRgDut1xIGgj4JlzsPGST/UWLoMZDUCj8gh4RK5ahjp1V3QQ==", "optional": true }, "@next/swc-linux-x64-musl": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.12.tgz", - "integrity": "sha512-kEAJmgYFhp0VL+eRWmUkVxLVunn7oL9Mdue/FS8yzRBVj7Z0AnIrHpTIeIUl1bbdQq1VaoOztnKicAjfkLTRCQ==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.13-canary.12.tgz", + "integrity": "sha512-HpHYIizHkGoEckN+XlcLZ42ojXpVNVrD7V+qFiXEBzSALzP5jc9y6Pj9u/dccAlq68regbSJvAFY04ZVfnA2SQ==", "optional": true }, "@next/swc-win32-arm64-msvc": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.12.tgz", - "integrity": "sha512-GMLuL/loR6yIIRTnPRY6UGbLL9MBdw2anxkOnANxvLvsml4F0HNIgvnU3Ej4BjbqMTNjD4hcPFdlEow4XHPdZA==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.13-canary.12.tgz", + "integrity": "sha512-SjVHvLMuGE9IaJyGxcxnPcJ/CE8EQoZ2Td3hfgGpzOdOu1hs+HOjv9ipUG33JG5A4PBzoQ1VY3d81LfdOTfZFw==", "optional": true }, "@next/swc-win32-ia32-msvc": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.12.tgz", - "integrity": "sha512-PhgNqN2Vnkm7XaMdRmmX0ZSwZXQAtamBVSa9A/V1dfKQCV1rjIZeiy/dbBnVYGdj63ANfsOR/30XpxP71W0eww==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.13-canary.12.tgz", + "integrity": "sha512-LIYmXkE+dMoYBoqU2HR0vVVUp927P4O5ohk4kR6d2tviNKpX7CPk0MQF+YWNlFrOJco4PTN22WBYhPhYSmPXcA==", "optional": true }, "@next/swc-win32-x64-msvc": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.12.tgz", - "integrity": "sha512-Z+56e/Ljt0bUs+T+jPjhFyxYBcdY2RIq9ELFU+qAMQMteHo7ymbV7CKmlcX59RI9C4YzN8PgMgLyAoi916b5HA==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.13-canary.12.tgz", + "integrity": "sha512-tnNDC+EIBmow2Y3pGXyIvQDhECSC8PwXgRflQnczwnWWNNLMq5fzy45gYLw/85NSqkQ6NvEz9B9+UGzAx3kW5Q==", "optional": true }, "@nicolo-ribaudo/eslint-scope-5-internals": { @@ -21663,8 +21630,7 @@ "@prisma/engines": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.0.0.tgz", - "integrity": "sha512-kyT/8fd0OpWmhAU5YnY7eP31brW1q1YrTGoblWrhQJDiN/1K+Z8S1kylcmtjqx5wsUGcP1HBWutayA/jtyt+sg==", - "dev": true + "integrity": "sha512-kyT/8fd0OpWmhAU5YnY7eP31brW1q1YrTGoblWrhQJDiN/1K+Z8S1kylcmtjqx5wsUGcP1HBWutayA/jtyt+sg==" }, "@prisma/engines-version": { "version": "4.17.0-26.6b0aef69b7cdfc787f822ecd7cdc76d5f1991584", @@ -21795,9 +21761,9 @@ }, "dependencies": { "uncontrollable": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.2.tgz", - "integrity": "sha512-/GDx+K1STGtpgTsj5Dj3J51YaKxZDblbCQHTH1zHLuoBEWodj6MjtRVv3TUijj1JYLRLSFsFzN8NV4M3QV4d9w==" + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==" } } }, @@ -22278,11 +22244,6 @@ } } }, - "@types/nprogress": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@types/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha512-1cYJrqq9GezNFPsWTZpFut/d4CjpZqA0vhqDUPFWYKF1oIyBz5qnoYMzR+0C/T96t3ebLAC1SSnwrVOm5/j74A==" - }, "@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -22849,9 +22810,9 @@ } }, "aws-sdk": { - "version": "2.1422.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1422.0.tgz", - "integrity": "sha512-dBHCT42s2NOrZVSeKQ+I0kPsAPN0QhbKv05gQFQL79yGIOqLZawWos8vtKSYdp9wEOpiIRttB7m6usYJObKpWA==", + "version": "2.1425.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1425.0.tgz", + "integrity": "sha512-DbY5z7E8RsrX8/0pMBKMuh/rWFic3AghtU2AWkUdzxDi0cUSK7rOSPS/OIURU9Rh0jaNXoA0ujBDdx/CC5CvRA==", "requires": { "buffer": "4.9.2", "events": "1.1.1", @@ -23269,9 +23230,9 @@ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, "bootstrap": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.0.tgz", - "integrity": "sha512-UnBV3E3v4STVNQdms6jSGO2CvOkjUMdDAVR2V5N4uCMdaIkaQjbcEAMqRimDHIs4uqBYzDAKCQwCB+97tJgHQw==" + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.1.tgz", + "integrity": "sha512-jzwza3Yagduci2x0rr9MeFSORjcHpt0lRZukZPZQJT1Dth5qzV7XcgGqYzi39KGAVYR8QEDVoO0ubFKOxzMG+g==" }, "brace-expansion": { "version": "1.1.11", @@ -23512,9 +23473,9 @@ }, "dependencies": { "node-fetch": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz", - "integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "requires": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", @@ -24606,27 +24567,27 @@ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, "eslint": { - "version": "8.45.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", - "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.46.0.tgz", + "integrity": "sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.1.0", - "@eslint/js": "8.44.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.1", + "@eslint/js": "^8.46.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.6.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.2", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -24703,9 +24664,9 @@ "dev": true }, "eslint-scope": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.1.tgz", - "integrity": "sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -24713,9 +24674,9 @@ } }, "eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", + "integrity": "sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==", "dev": true }, "glob-parent": { @@ -25010,9 +24971,9 @@ }, "dependencies": { "eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", + "integrity": "sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==", "dev": true } } @@ -27957,19 +27918,29 @@ } }, "mdast-util-to-markdown": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.3.0.tgz", - "integrity": "sha512-6tUSs4r+KK4JGTTiQ7FfHmVOaDrLQJPmpjD6wPMlHGUVXoG9Vjc3jIeP+uyBWRf8clwB2blM+W7+KrlMYQnftA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz", + "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==", "requires": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^3.0.0", "mdast-util-to-string": "^3.0.0", "micromark-util-decode-string": "^1.0.0", "unist-util-visit": "^4.0.0", "zwitch": "^2.0.0" }, "dependencies": { + "mdast-util-phrasing": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz", + "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==", + "requires": { + "@types/mdast": "^3.0.0", + "unist-util-is": "^5.0.0" + } + }, "mdast-util-to-string": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", @@ -29125,20 +29096,20 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "next": { - "version": "13.4.12", - "resolved": "https://registry.npmjs.org/next/-/next-13.4.12.tgz", - "integrity": "sha512-eHfnru9x6NRmTMcjQp6Nz0J4XH9OubmzOa7CkWL+AUrUxpibub3vWwttjduu9No16dug1kq04hiUUpo7J3m3Xw==", + "version": "13.4.13-canary.12", + "resolved": "https://registry.npmjs.org/next/-/next-13.4.13-canary.12.tgz", + "integrity": "sha512-HVtCufObzWNAPyHpElMEU4b/C7jbmJLS6Xp8to0WFuPwhKVCfmYTO/S9O6nmuflHC+TR9yfh6HGRZ8N9RM8g/g==", "requires": { - "@next/env": "13.4.12", - "@next/swc-darwin-arm64": "13.4.12", - "@next/swc-darwin-x64": "13.4.12", - "@next/swc-linux-arm64-gnu": "13.4.12", - "@next/swc-linux-arm64-musl": "13.4.12", - "@next/swc-linux-x64-gnu": "13.4.12", - "@next/swc-linux-x64-musl": "13.4.12", - "@next/swc-win32-arm64-msvc": "13.4.12", - "@next/swc-win32-ia32-msvc": "13.4.12", - "@next/swc-win32-x64-msvc": "13.4.12", + "@next/env": "13.4.13-canary.12", + "@next/swc-darwin-arm64": "13.4.13-canary.12", + "@next/swc-darwin-x64": "13.4.13-canary.12", + "@next/swc-linux-arm64-gnu": "13.4.13-canary.12", + "@next/swc-linux-arm64-musl": "13.4.13-canary.12", + "@next/swc-linux-x64-gnu": "13.4.13-canary.12", + "@next/swc-linux-x64-musl": "13.4.13-canary.12", + "@next/swc-win32-arm64-msvc": "13.4.13-canary.12", + "@next/swc-win32-ia32-msvc": "13.4.13-canary.12", + "@next/swc-win32-x64-msvc": "13.4.13-canary.12", "@swc/helpers": "0.5.1", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -29174,16 +29145,6 @@ "resolved": "https://registry.npmjs.org/next-seo/-/next-seo-6.1.0.tgz", "integrity": "sha512-iMBpFoJsR5zWhguHJvsoBDxDSmdYTHtnVPB1ij+CD0NReQCP78ZxxbdL9qkKIf4oEuZEqZkrjAQLB0bkII7RYA==" }, - "nextjs-progressbar": { - "version": "0.0.16", - "resolved": "https://registry.npmjs.org/nextjs-progressbar/-/nextjs-progressbar-0.0.16.tgz", - "integrity": "sha512-GV0fD38EMD3vSDCmkq+tObmoup6QA91a6a9MxGuhJZuRk/9TNsrHGnIQQQ/sggkMkXuT4fBgF6jRjFwScDT3zA==", - "requires": { - "@types/nprogress": "^0.2.0", - "nprogress": "^0.2.0", - "prop-types": "^15.8.1" - } - }, "noble-secp256k1": { "version": "1.2.14", "resolved": "https://registry.npmjs.org/noble-secp256k1/-/noble-secp256k1-1.2.14.tgz", @@ -30033,9 +29994,9 @@ "integrity": "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==" }, "preact-render-to-string": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz", - "integrity": "sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz", + "integrity": "sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==", "requires": { "pretty-format": "^3.8.0" } @@ -30065,7 +30026,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.0.0.tgz", "integrity": "sha512-KYWk83Fhi1FH59jSpavAYTt2eoMVW9YKgu8ci0kuUnt6Dup5Qy47pcB4/TLmiPAbhGrxxSz7gsSnJcCmkyPANA==", - "dev": true, "requires": { "@prisma/engines": "5.0.0" } @@ -32422,17 +32382,17 @@ "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, "tldts": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.0.12.tgz", - "integrity": "sha512-a3xVdMF9FgBqOR6bo51jA90cE0PyKiGIN/L0F8bOJOgMHJ+CujbNDnT3YSYlr/Kod4DJA5ihfJD5tiByx6njgg==", + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.0.13.tgz", + "integrity": "sha512-9v+ZsSU8yBywX6RjT6/pNmwPzTVIeIi7sEiaFDhgsbXZRtvKKrWSiP4K0NTLm1rEvlfKYM24wxxcq7wMr4JRDA==", "requires": { - "tldts-core": "^6.0.12" + "tldts-core": "^6.0.13" }, "dependencies": { "tldts-core": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.0.12.tgz", - "integrity": "sha512-TYHGh0SJ+MUE0tg5LeDyNMmilUU8VD7fi+o74RGl3xwnakzCjpTFVTn8DHWiDJQmfG768ldqRPSQrvTP6CPjpg==" + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.0.13.tgz", + "integrity": "sha512-LcXhi9dyMeMBTMhpOSUUG4QwiMSADkcdmTg59rXkQyxoWTnyXgvpzoqJGvrhWTDwcs2NseybtqDTA6TWZgNxOA==" } } }, @@ -33181,9 +33141,9 @@ } }, "web-push": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/web-push/-/web-push-3.6.3.tgz", - "integrity": "sha512-3RlA0lRmLcwlHCRR94Tz+Fw6wPtm0lFm8oyukQunlEIarANxE84Ox9XBgF4+jNlXgO40DIwblOiC43oR46helA==", + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/web-push/-/web-push-3.6.4.tgz", + "integrity": "sha512-An4nhiYuCPJkD51hXid7OIO3TACJsSUhj6XWDNvCDiLCS5ucEkhPUnh/s+jOWAJUUDASGHkuU8hFHg+mX+4vLQ==", "requires": { "asn1.js": "^5.3.0", "http_ece": "1.1.0", diff --git a/package.json b/package.json index ba5ca349..823a1536 100644 --- a/package.json +++ b/package.json @@ -6,11 +6,11 @@ "dev": "NODE_OPTIONS='--trace-warnings' next dev", "build": "next build", "migrate": "prisma migrate deploy", - "start": "NODE_OPTIONS='--trace-warnings' next start -p $PORT" + "start": "NODE_OPTIONS='--trace-warnings' next start -p $PORT --keepAliveTimeout 120000" }, "dependencies": { "@apollo/client": "^3.7.17", - "@apollo/server": "^4.8.1", + "@apollo/server": "^4.9.0", "@as-integrations/next": "^2.0.1", "@auth/prisma-adapter": "^1.0.1", "@graphql-tools/schema": "^10.0.0", @@ -22,12 +22,11 @@ "acorn": "^8.10.0", "ajv": "^8.12.0", "async-retry": "^1.3.1", - "aws-sdk": "^2.1422.0", + "aws-sdk": "^2.1425.0", "babel-plugin-inline-react-svg": "^2.0.2", "bech32": "^2.0.0", "bolt11": "^1.4.1", - "bootstrap": "^5.3.0", - "browserslist": "^4.21.4", + "bootstrap": "^5.3.1", "canonical-json": "0.0.4", "clipboard-copy": "^4.0.1", "cross-fetch": "^4.0.0", @@ -45,18 +44,19 @@ "mdast-util-gfm": "^3.0.0", "mdast-util-to-string": "^4.0.0", "micromark-extension-gfm": "^3.0.0", - "next": "^13.4.12", + "next": "^13.4.13-canary.12", "next-auth": "^4.22.3", "next-plausible": "^3.10.1", "next-seo": "^6.1.0", - "nextjs-progressbar": "0.0.16", "node-s3-url-encode": "^0.0.4", "nodemailer": "^6.9.4", "nostr": "^0.2.8", + "nprogress": "^0.2.0", "opentimestamps": "^0.4.9", "page-metadata-parser": "^1.1.4", "pageres": "^7.1.0", "pg-boss": "^9.0.3", + "prisma": "^5.0.0", "qrcode.react": "^3.1.0", "react": "^18.2.0", "react-avatar-editor": "^13.0.0", @@ -75,11 +75,11 @@ "remark-gfm": "^3.0.1", "remove-markdown": "^0.5.0", "sass": "^1.64.1", - "tldts": "^6.0.12", + "tldts": "^6.0.13", "typescript": "^5.1.6", "unist-util-visit": "^5.0.0", "url-unshort": "^6.1.0", - "web-push": "^3.6.2", + "web-push": "^3.6.4", "webln": "^0.3.2", "webpack": "^5.88.2", "workbox-navigation-preload": "^7.0.0", @@ -92,7 +92,7 @@ "yup": "^1.2.0" }, "engines": { - "node": "18.16.1" + "node": "18.17.0" }, "standard": { "parser": "@babel/eslint-parser", @@ -107,8 +107,7 @@ "@babel/core": "^7.22.9", "@babel/eslint-parser": "^7.22.9", "@next/eslint-plugin-next": "^13.4.12", - "eslint": "^8.45.0", - "prisma": "^5.0.0", + "eslint": "^8.46.0", "standard": "^17.1.0" } } diff --git a/pages/_app.js b/pages/_app.js index 8c7f4458..af7b4fcd 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -3,7 +3,6 @@ import { ApolloProvider, gql } from '@apollo/client' import { MeProvider } from '../components/me' import PlausibleProvider from 'next-plausible' import getApolloClient from '../lib/apollo' -import NextNProgress from 'nextjs-progressbar' import { PriceProvider } from '../components/price' import Head from 'next/head' import { useRouter } from 'next/dist/client/router' @@ -12,8 +11,13 @@ import { ShowModalProvider } from '../components/modal' import ErrorBoundary from '../components/error-boundary' import { LightningProvider } from '../components/lightning' import { ServiceWorkerProvider } from '../components/serviceworker' +import { SSR } from '../lib/constants' +import NProgress from 'nprogress' +import 'nprogress/nprogress.css' -const SSR = typeof window === 'undefined' +NProgress.configure({ + showSpinner: false +}) function writeQuery (client, apollo, data) { if (apollo && data) { @@ -21,8 +25,8 @@ function writeQuery (client, apollo, data) { query: gql`${apollo.query}`, data, variables: apollo.variables, - broadcast: !SSR, - overwrite: SSR + overwrite: SSR, + broadcast: false }) } } @@ -32,48 +36,49 @@ function MyApp ({ Component, pageProps: { ...props } }) { const router = useRouter() useEffect(() => { + const nprogressStart = (_, { shallow }) => !shallow && NProgress.start() + const nprogressDone = (_, { shallow }) => !shallow && NProgress.done() + + router.events.on('routeChangeStart', nprogressStart) + router.events.on('routeChangeComplete', nprogressDone) + router.events.on('routeChangeError', nprogressDone) + + if (!props?.apollo) return // HACK: 'cause there's no way to tell Next to skip SSR // So every page load, we modify the route in browser history // to point to the same page but without SSR, ie ?nodata=true // this nodata var will get passed to the server on back/foward and // 1. prevent data from reloading and 2. perserve scroll // (2) is not possible while intercepting nav with beforePopState - if (router.query.nodata) return - router.replace({ pathname: router.pathname, query: { ...router.query, nodata: true } }, router.asPath, { ...router.options, shallow: true }).catch((e) => { // workaround for https://github.com/vercel/next.js/issues/37362 if (!e.cancelled) { + console.log(e) throw e } }) - }, [router.pathname, router.query]) + + return () => { + router.events.off('routeChangeStart', nprogressStart) + router.events.off('routeChangeComplete', nprogressDone) + router.events.off('routeChangeError', nprogressDone) + } + }, [router.asPath, props?.apollo]) /* If we are on the client, we populate the apollo cache with the ssr data */ const { apollo, ssrData, me, price, ...otherProps } = props - // if we are on the server, useEffect won't run - if (SSR && client) { - writeQuery(client, apollo, ssrData) - } useEffect(() => { writeQuery(client, apollo, ssrData) }, [client, apollo, ssrData]) return ( <> - diff --git a/pages/_document.js b/pages/_document.js index d7441a3a..70f8cd7a 100644 --- a/pages/_document.js +++ b/pages/_document.js @@ -23,8 +23,43 @@ class MyDocument extends Document { }} /> - + + @@ -59,7 +94,6 @@ class MyDocument extends Document { -