mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-04-26 05:05:21 -04:00
refactor .js files to ES modules where possible
This commit is contained in:
parent
e66dc37c41
commit
e1a26d5257
36
.env.example
36
.env.example
@ -1,9 +1,37 @@
|
||||
# absolutely required:
|
||||
# required. falls back to relative URLs in most places, but still must be set in the Vercel dashboard for production.
|
||||
# include https:// and leave out the trailing slash, e.g. "https://jarv.is".
|
||||
NEXT_PUBLIC_BASE_URL=
|
||||
|
||||
# required. storage for hit counter endpoints at /api/count and /api/hits.
|
||||
# currently uses MySQL, but this can be changed to use Postgres, SQLite, etc in prisma/schema.prisma.
|
||||
# https://www.prisma.io/docs/orm/reference/connection-urls#examples
|
||||
# https://planetscale.com/docs/concepts/connection-strings
|
||||
# note: this might be automatically provided by a Vercel integration; see: https://vercel.com/integrations#databases
|
||||
# vercel env pull .env.local --environment=production
|
||||
DATABASE_URL=
|
||||
|
||||
# requred. used for /projects grid, built with SSG. only needs the "public_repo" scope since we don't need/want to
|
||||
# showcase any private repositories, obviously.
|
||||
# https://github.com/settings/tokens/new?scopes=public_repo
|
||||
GH_PUBLIC_TOKEN=
|
||||
|
||||
# optional (but not really):
|
||||
# required for production. sends contact form submissions via /api/contact.
|
||||
# https://resend.com/api-keys
|
||||
RESEND_API_KEY=
|
||||
# optional. send submissions from noreply@{RESEND_DOMAIN}; defaults to onboarding@resend.dev. sender's real email is
|
||||
# passed via a Reply-To header. setting this makes zero difference to the user.
|
||||
# https://resend.com/docs/send-with-nodemailer-smtp
|
||||
RESEND_DOMAIN=
|
||||
|
||||
# required for production. falls back to testing keys if not set or in dev environment:
|
||||
# https://docs.hcaptcha.com/#integration-testing-test-keys
|
||||
# site key must be prefixed with NEXT_PUBLIC_ since it is used to embed the actual captcha widget.
|
||||
# https://dashboard.hcaptcha.com/sites
|
||||
NEXT_PUBLIC_HCAPTCHA_SITE_KEY=
|
||||
# used only for backend validation of contact form submissions on /api/contact.
|
||||
HCAPTCHA_SECRET_KEY=
|
||||
MAILGUN_SMTP_USER=
|
||||
MAILGUN_SMTP_PASS=
|
||||
|
||||
# optional. sets the site ID of the fathom analytics script.
|
||||
# https://app.usefathom.com/sites
|
||||
# https://usefathom.com/ref/ZEYG0O (referral link)
|
||||
NEXT_PUBLIC_FATHOM_SITE_ID=
|
||||
|
@ -1,4 +1,6 @@
|
||||
// https://prettier.io/docs/en/options.html
|
||||
/**
|
||||
* @type {import("prettier").Config}
|
||||
*/
|
||||
module.exports = {
|
||||
singleQuote: false,
|
||||
jsxSingleQuote: false,
|
@ -1,7 +1,6 @@
|
||||
import HCaptcha from "@hcaptcha/react-hcaptcha";
|
||||
import useHasMounted from "../../hooks/useHasMounted";
|
||||
import useTheme from "../../hooks/useTheme";
|
||||
import { hcaptchaSiteKey } from "../../lib/config";
|
||||
|
||||
export type CaptchaProps = {
|
||||
size?: "normal" | "compact" | "invisible";
|
||||
@ -28,7 +27,7 @@ const Captcha = ({ size = "normal", theme, className, ...rest }: CaptchaProps) =
|
||||
<div className={className}>
|
||||
{hasMounted && (
|
||||
<HCaptcha
|
||||
sitekey={hcaptchaSiteKey || "10000000-ffff-ffff-ffff-000000000001"}
|
||||
sitekey={process.env.NEXT_PUBLIC_HCAPTCHA_SITE_KEY || "10000000-ffff-ffff-ffff-000000000001"}
|
||||
reCaptchaCompat={false}
|
||||
tabIndex={0}
|
||||
size={size}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import Giscus from "@giscus/react";
|
||||
import useTheme from "../../hooks/useTheme";
|
||||
import { styled, theme } from "../../lib/styles/stitches.config";
|
||||
import { giscusConfig } from "../../lib/config";
|
||||
import config from "../../lib/config";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
import type { GiscusProps } from "@giscus/react";
|
||||
|
||||
@ -23,7 +23,7 @@ const Comments = ({ title, ...rest }: CommentsProps) => {
|
||||
return (
|
||||
<Wrapper {...rest}>
|
||||
<Giscus
|
||||
{...(giscusConfig as GiscusProps)}
|
||||
{...(config.giscusConfig as GiscusProps)}
|
||||
term={title}
|
||||
mapping="specific"
|
||||
reactionsEnabled="1"
|
||||
|
@ -174,10 +174,10 @@ const ContactForm = ({ className }: ContactFormProps) => {
|
||||
.catch((error) => {
|
||||
setSuccess(false);
|
||||
|
||||
if (error.message === "USER_MISSING_DATA") {
|
||||
if (error.message === "missing_data") {
|
||||
// this should be validated client-side but it's also checked server-side just in case someone slipped past
|
||||
setFeedback("Please make sure that all fields are properly filled in.");
|
||||
} else if (error.message === "USER_INVALID_CAPTCHA") {
|
||||
} else if (error.message === "invalid_captcha") {
|
||||
// missing/invalid captcha
|
||||
setFeedback("Did you complete the CAPTCHA? (If you're human, that is...)");
|
||||
} else {
|
||||
|
@ -2,7 +2,7 @@ import Link from "../Link";
|
||||
import { GoHeartFill } from "react-icons/go";
|
||||
import { SiNextdotjs } from "react-icons/si";
|
||||
import { styled, theme, keyframes } from "../../lib/styles/stitches.config";
|
||||
import * as config from "../../lib/config";
|
||||
import config from "../../lib/config";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
const Wrapper = styled("footer", {
|
||||
|
@ -5,7 +5,7 @@ import HitCounter from "../HitCounter";
|
||||
import PostTitle from "../PostTitle";
|
||||
import { FiCalendar, FiTag, FiEdit, FiEye } from "react-icons/fi";
|
||||
import { styled, theme } from "../../lib/styles/stitches.config";
|
||||
import * as config from "../../lib/config";
|
||||
import config from "../../lib/config";
|
||||
import type { PostFrontMatter } from "../../types";
|
||||
|
||||
const Wrapper = styled("div", {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import Link from "../Link";
|
||||
import Image from "../Image";
|
||||
import { styled, theme } from "../../lib/styles/stitches.config";
|
||||
import { authorName } from "../../lib/config";
|
||||
import config from "../../lib/config";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
import selfieJpg from "../../public/static/images/selfie.jpg";
|
||||
@ -52,10 +52,10 @@ export type SelfieProps = Omit<ComponentPropsWithoutRef<typeof Link>, "href">;
|
||||
|
||||
const Selfie = ({ ...rest }: SelfieProps) => {
|
||||
return (
|
||||
<SelfieLink href="/" rel="author" title={authorName} underline={false} {...rest}>
|
||||
<SelfieLink href="/" rel="author" title={config.authorName} underline={false} {...rest}>
|
||||
<CircleImage
|
||||
src={selfieJpg}
|
||||
alt={`Photo of ${authorName}`}
|
||||
alt={`Photo of ${config.authorName}`}
|
||||
width={70}
|
||||
height={70}
|
||||
quality={60}
|
||||
@ -63,7 +63,7 @@ const Selfie = ({ ...rest }: SelfieProps) => {
|
||||
inline
|
||||
priority
|
||||
/>
|
||||
<Name>{authorName}</Name>
|
||||
<Name>{config.authorName}</Name>
|
||||
</SelfieLink>
|
||||
);
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
// @ts-check
|
||||
// do not convert to ESM and/or TS -- this needs to be imported in CJS files like next.config.js too
|
||||
module.exports = {
|
||||
|
||||
const config = {
|
||||
// Site info
|
||||
siteName: "Jake Jarvis",
|
||||
siteDomain: "jarv.is",
|
||||
@ -17,8 +17,6 @@ module.exports = {
|
||||
githubRepo: "jakejarvis/jarv.is",
|
||||
verifyGoogle: "qQhmLTwjNWYgQ7W42nSTq63xIrTch13X_11mmxBE9zk",
|
||||
verifyBing: "164551986DA47F7F6FC0D21A93FFFCA6",
|
||||
fathomSiteId: "PIUEIVIZ",
|
||||
hcaptchaSiteKey: "60d959de-b01b-4e22-a901-ce395ed086cb",
|
||||
giscusConfig: {
|
||||
// https://github.com/giscus/giscus-component/tree/main/packages/react#readme
|
||||
repo: "jakejarvis/jarv.is",
|
||||
@ -41,3 +39,5 @@ module.exports = {
|
||||
mastodon: "fediverse.jarv.is/@jake",
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import * as config from ".";
|
||||
import config from ".";
|
||||
import { meJpg, faviconPng, faviconIco, appleTouchIconPng } from "./favicons";
|
||||
|
||||
import type { DefaultSeoProps, SocialProfileJsonLdProps, ArticleJsonLdProps } from "next-seo";
|
||||
|
@ -1,21 +1,20 @@
|
||||
import { Feed } from "feed";
|
||||
import { getAllPosts } from "./posts";
|
||||
import * as config from "../config";
|
||||
import config from "../config";
|
||||
import { meJpg } from "../config/favicons";
|
||||
import type { GetServerSideProps } from "next";
|
||||
|
||||
export type GetServerSideFeedProps = GetServerSideProps<Record<string, never>>;
|
||||
|
||||
export type BuildFeedOptions = {
|
||||
edgeCacheAge?: number; // in seconds, defaults to 43200 (12 hours)
|
||||
format: "rss" | "atom" | "json";
|
||||
};
|
||||
|
||||
// handles literally *everything* about building the server-side rss/atom feeds and writing the response.
|
||||
// all the page needs to do is `return buildFeed(context, "rss")` from getServerSideProps.
|
||||
export const buildFeed = async (
|
||||
context: Parameters<GetServerSideFeedProps>[0],
|
||||
type: "rss" | "atom" | "json",
|
||||
options?: BuildFeedOptions
|
||||
options: BuildFeedOptions
|
||||
): Promise<ReturnType<GetServerSideFeedProps>> => {
|
||||
const { res } = context;
|
||||
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || `https://${config.siteDomain}`;
|
||||
@ -59,26 +58,23 @@ export const buildFeed = async (
|
||||
});
|
||||
});
|
||||
|
||||
// cache on edge for 12 hours by default
|
||||
res.setHeader(
|
||||
"cache-control",
|
||||
`public, max-age=0, s-maxage=${options?.edgeCacheAge ?? 86400}, stale-while-revalidate`
|
||||
);
|
||||
// cache on edge for 24 hours by default
|
||||
res.setHeader("cache-control", `public, max-age=0, s-maxage=86400, stale-while-revalidate`);
|
||||
|
||||
// generates RSS by default
|
||||
if (type === "rss") {
|
||||
if (options.format === "rss") {
|
||||
res.setHeader("content-type", "application/rss+xml; charset=utf-8");
|
||||
res.write(feed.rss2());
|
||||
} else if (type === "atom") {
|
||||
} else if (options.format === "atom") {
|
||||
res.setHeader("content-type", "application/atom+xml; charset=utf-8");
|
||||
res.write(feed.atom1());
|
||||
} else if (type === "json") {
|
||||
} else if (options.format === "json") {
|
||||
// rare but including as an option because why not...
|
||||
// https://www.jsonfeed.org/
|
||||
res.setHeader("content-type", "application/feed+json; charset=utf-8");
|
||||
res.write(feed.json1());
|
||||
} else {
|
||||
throw new TypeError(`Invalid feed type "${type}", must be "rss", "atom", or "json".`);
|
||||
throw new TypeError(`Invalid feed type "${options.format}", must be "rss", "atom", or "json".`);
|
||||
}
|
||||
|
||||
res.end();
|
||||
|
@ -5,7 +5,7 @@ import dayjsRelativeTime from "dayjs/plugin/relativeTime";
|
||||
import dayjsLocalizedFormat from "dayjs/plugin/localizedFormat";
|
||||
import dayjsAdvancedFormat from "dayjs/plugin/advancedFormat";
|
||||
import "dayjs/locale/en";
|
||||
import { timeZone } from "../config";
|
||||
import config from "../config";
|
||||
|
||||
const IsomorphicDayJs = (date?: dayjs.ConfigType): dayjs.Dayjs => {
|
||||
// plugins
|
||||
@ -15,7 +15,7 @@ const IsomorphicDayJs = (date?: dayjs.ConfigType): dayjs.Dayjs => {
|
||||
dayjs.extend(dayjsLocalizedFormat);
|
||||
dayjs.extend(dayjsAdvancedFormat);
|
||||
|
||||
return dayjs(date).locale("en").tz(timeZone).clone();
|
||||
return dayjs(date).locale("en").tz(config.timeZone).clone();
|
||||
};
|
||||
|
||||
// simple wrapper around dayjs.format() to normalize timezone across the site, both server and client side, to prevent
|
||||
|
162
next.config.js
162
next.config.js
@ -1,162 +0,0 @@
|
||||
// @ts-check
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const config = require("./lib/config");
|
||||
|
||||
/**
|
||||
* @type {import("next").NextConfig}
|
||||
*/
|
||||
const nextConfig = {
|
||||
swcMinify: true,
|
||||
reactStrictMode: true,
|
||||
trailingSlash: true,
|
||||
productionBrowserSourceMaps: true,
|
||||
transpilePackages: [
|
||||
"@novnc/novnc",
|
||||
"react-tweet", // https://react-tweet.vercel.app/next#troubleshooting
|
||||
],
|
||||
env: {
|
||||
// freeze timestamp at build time for when server-side pages need a "last updated" date. calling Date.now() from
|
||||
// pages using getServerSideProps will return the current(ish) time instead, which is usually not what we want.
|
||||
RELEASE_DATE: new Date().toISOString(),
|
||||
},
|
||||
images: {
|
||||
deviceSizes: [640, 750, 828, 1080, 1200, 1920],
|
||||
formats: ["image/avif", "image/webp"],
|
||||
remotePatterns: [
|
||||
{ protocol: "https", hostname: "pbs.twimg.com" },
|
||||
{ protocol: "https", hostname: "abs.twimg.com" },
|
||||
],
|
||||
},
|
||||
experimental: {
|
||||
largePageDataBytes: 512 * 1000, // raise getStaticProps limit to 512 kB since compiled MDX will exceed the default.
|
||||
optimisticClientCache: false, // https://github.com/vercel/next.js/discussions/40268#discussioncomment-3572642
|
||||
},
|
||||
eslint: {
|
||||
// https://nextjs.org/docs/basic-features/eslint#linting-custom-directories-and-files
|
||||
dirs: ["components", "contexts", "hooks", "lib", "pages", "types"],
|
||||
},
|
||||
headers: async () => [
|
||||
{
|
||||
source: "/:path(.*)",
|
||||
headers: [
|
||||
{
|
||||
// https://gitweb.torproject.org/tor-browser-spec.git/tree/proposals/100-onion-location-header.txt
|
||||
key: "Onion-Location",
|
||||
value: config.onionDomain ? `${config.onionDomain}/:path*` : "",
|
||||
},
|
||||
{
|
||||
// 🥛
|
||||
key: "x-got-milk",
|
||||
value: "2%",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
source: "/pubkey.asc",
|
||||
headers: [
|
||||
{
|
||||
key: "Content-Type",
|
||||
value: "text/plain; charset=utf-8",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
rewrites: async () => ({
|
||||
beforeFiles: [
|
||||
{ source: "/favicon.ico", destination: "/static/favicons/favicon.ico" },
|
||||
{ source: "/favicon.png", destination: "/static/favicons/favicon.png" },
|
||||
{ source: "/apple-touch-icon.png", destination: "/static/favicons/apple-touch-icon.png" },
|
||||
{ source: "/apple-touch-icon-precomposed.png", destination: "/static/favicons/apple-touch-icon.png" },
|
||||
|
||||
// https://github.com/jakejarvis/tweets/deployments/github-pages
|
||||
{
|
||||
source: "/tweets/:path*/",
|
||||
destination: "https://jakejarvis.github.io/tweets/:path*/",
|
||||
},
|
||||
{
|
||||
// workaround for broken trailing slash redirects:
|
||||
// https://github.com/vercel/next.js/discussions/36219#discussioncomment-4167863
|
||||
source: "/tweets/:path*",
|
||||
destination: "https://jakejarvis.github.io/tweets/:path*",
|
||||
},
|
||||
],
|
||||
afterFiles: [
|
||||
{
|
||||
// access security.txt, etc at both /security.txt and /.well-known/security.txt
|
||||
source: "/.well-known/:slug.txt",
|
||||
destination: "/:slug.txt",
|
||||
},
|
||||
],
|
||||
fallback: [],
|
||||
}),
|
||||
redirects: async () => [
|
||||
{
|
||||
source: "/stats",
|
||||
destination: `https://app.usefathom.com/share/${config.fathomSiteId}/${config.siteDomain}`,
|
||||
permanent: false,
|
||||
},
|
||||
|
||||
// NOTE: don't remove this, it ensures de-AMPing the site hasn't offended our google overlords too badly!
|
||||
// https://developers.google.com/search/docs/advanced/experience/remove-amp#remove-only-amp
|
||||
{ source: "/notes/:slug/amp.html", destination: "/notes/:slug/", permanent: true },
|
||||
|
||||
// mastodon via subdomain:
|
||||
// https://docs.joinmastodon.org/admin/config/#web_domain
|
||||
{
|
||||
source: "/.well-known/host-meta:path*",
|
||||
destination: "https://fediverse.jarv.is/.well-known/host-meta:path*",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/.well-known/webfinger:path*",
|
||||
destination: "https://fediverse.jarv.is/.well-known/webfinger:path*",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/.well-known/nodeinfo:path*",
|
||||
destination: "https://fediverse.jarv.is/.well-known/nodeinfo:path*",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/@jake",
|
||||
destination: "https://fediverse.jarv.is/@jake",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/@jake/:path*",
|
||||
destination: "https://fediverse.jarv.is/@jake/:path*",
|
||||
permanent: true,
|
||||
},
|
||||
|
||||
// google search console has tons of 404s for images prefixed with /public... why? no clue.
|
||||
{ source: "/public/static/:path*", destination: "/static/:path*", permanent: true },
|
||||
|
||||
// remnants of previous sites/CMSes:
|
||||
{ source: "/index.xml", destination: "/feed.xml", permanent: true },
|
||||
{ source: "/feed", destination: "/feed.xml", permanent: true },
|
||||
{ source: "/rss", destination: "/feed.xml", permanent: true },
|
||||
{ source: "/blog/:path*", destination: "/notes/", permanent: true },
|
||||
{ source: "/archives/:path*", destination: "/notes/", permanent: true },
|
||||
{ source: "/resume", destination: "/static/resume.pdf", permanent: false },
|
||||
{ source: "/resume.pdf", destination: "/static/resume.pdf", permanent: false },
|
||||
|
||||
// WordPress permalinks:
|
||||
{
|
||||
source: "/2016/02/28/millenial-with-hillary-clinton",
|
||||
destination: "/notes/millenial-with-hillary-clinton/",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/2018/12/04/how-to-shrink-linux-virtual-disk-vmware",
|
||||
destination: "/notes/how-to-shrink-linux-virtual-disk-vmware/",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/2018/12/10/cool-bash-tricks-for-your-terminal-dotfiles",
|
||||
destination: "/notes/cool-bash-tricks-for-your-terminal-dotfiles/",
|
||||
permanent: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = nextConfig;
|
166
next.config.mjs
Normal file
166
next.config.mjs
Normal file
@ -0,0 +1,166 @@
|
||||
// @ts-check
|
||||
// eslint-disable import/no-anonymous-default-export
|
||||
|
||||
import config from "./lib/config/index.js";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export default (phase, { defaultConfig }) => {
|
||||
/**
|
||||
* @type {import('next').NextConfig}
|
||||
*/
|
||||
const nextConfig = {
|
||||
swcMinify: true,
|
||||
reactStrictMode: true,
|
||||
trailingSlash: true,
|
||||
productionBrowserSourceMaps: true,
|
||||
transpilePackages: [
|
||||
"@novnc/novnc",
|
||||
"react-tweet", // https://react-tweet.vercel.app/next#troubleshooting
|
||||
],
|
||||
env: {
|
||||
// freeze timestamp at build time for when server-side pages need a "last updated" date. calling Date.now() from
|
||||
// pages using getServerSideProps will return the current(ish) time instead, which is usually not what we want.
|
||||
RELEASE_DATE: new Date().toISOString(),
|
||||
},
|
||||
images: {
|
||||
deviceSizes: [640, 750, 828, 1080, 1200, 1920],
|
||||
formats: ["image/avif", "image/webp"],
|
||||
remotePatterns: [
|
||||
{ protocol: "https", hostname: "pbs.twimg.com" },
|
||||
{ protocol: "https", hostname: "abs.twimg.com" },
|
||||
],
|
||||
},
|
||||
experimental: {
|
||||
largePageDataBytes: 512 * 1000, // raise getStaticProps limit to 512 kB since compiled MDX will exceed the default.
|
||||
optimisticClientCache: false, // https://github.com/vercel/next.js/discussions/40268#discussioncomment-3572642
|
||||
},
|
||||
eslint: {
|
||||
// https://nextjs.org/docs/basic-features/eslint#linting-custom-directories-and-files
|
||||
dirs: ["components", "contexts", "hooks", "lib", "pages", "types"],
|
||||
},
|
||||
headers: async () => [
|
||||
{
|
||||
source: "/:path(.*)",
|
||||
headers: [
|
||||
{
|
||||
// https://gitweb.torproject.org/tor-browser-spec.git/tree/proposals/100-onion-location-header.txt
|
||||
key: "Onion-Location",
|
||||
value: config.onionDomain ? `${config.onionDomain}/:path*` : "",
|
||||
},
|
||||
{
|
||||
// 🥛
|
||||
key: "x-got-milk",
|
||||
value: "2%",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
source: "/pubkey.asc",
|
||||
headers: [
|
||||
{
|
||||
key: "Content-Type",
|
||||
value: "text/plain; charset=utf-8",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
rewrites: async () => ({
|
||||
beforeFiles: [
|
||||
{ source: "/favicon.ico", destination: "/static/favicons/favicon.ico" },
|
||||
{ source: "/favicon.png", destination: "/static/favicons/favicon.png" },
|
||||
{ source: "/apple-touch-icon.png", destination: "/static/favicons/apple-touch-icon.png" },
|
||||
{ source: "/apple-touch-icon-precomposed.png", destination: "/static/favicons/apple-touch-icon.png" },
|
||||
|
||||
// https://github.com/jakejarvis/tweets/deployments/github-pages
|
||||
{
|
||||
source: "/tweets/:path*/",
|
||||
destination: "https://jakejarvis.github.io/tweets/:path*/",
|
||||
},
|
||||
{
|
||||
// workaround for broken trailing slash redirects:
|
||||
// https://github.com/vercel/next.js/discussions/36219#discussioncomment-4167863
|
||||
source: "/tweets/:path*",
|
||||
destination: "https://jakejarvis.github.io/tweets/:path*",
|
||||
},
|
||||
],
|
||||
afterFiles: [
|
||||
{
|
||||
// access security.txt, etc at both /security.txt and /.well-known/security.txt
|
||||
source: "/.well-known/:slug.txt",
|
||||
destination: "/:slug.txt",
|
||||
},
|
||||
],
|
||||
fallback: [],
|
||||
}),
|
||||
redirects: async () => [
|
||||
{
|
||||
source: "/stats",
|
||||
destination: `https://app.usefathom.com/share/${process.env.NEXT_PUBLIC_FATHOM_SITE_ID || ""}/${config.siteDomain}`,
|
||||
permanent: false,
|
||||
},
|
||||
|
||||
// NOTE: don't remove this, it ensures de-AMPing the site hasn't offended our google overlords too badly!
|
||||
// https://developers.google.com/search/docs/advanced/experience/remove-amp#remove-only-amp
|
||||
{ source: "/notes/:slug/amp.html", destination: "/notes/:slug/", permanent: true },
|
||||
|
||||
// mastodon via subdomain:
|
||||
// https://docs.joinmastodon.org/admin/config/#web_domain
|
||||
{
|
||||
source: "/.well-known/host-meta:path*",
|
||||
destination: "https://fediverse.jarv.is/.well-known/host-meta:path*",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/.well-known/webfinger:path*",
|
||||
destination: "https://fediverse.jarv.is/.well-known/webfinger:path*",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/.well-known/nodeinfo:path*",
|
||||
destination: "https://fediverse.jarv.is/.well-known/nodeinfo:path*",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/@jake",
|
||||
destination: "https://fediverse.jarv.is/@jake",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/@jake/:path*",
|
||||
destination: "https://fediverse.jarv.is/@jake/:path*",
|
||||
permanent: true,
|
||||
},
|
||||
|
||||
// google search console has tons of 404s for images prefixed with /public... why? no clue.
|
||||
{ source: "/public/static/:path*", destination: "/static/:path*", permanent: true },
|
||||
|
||||
// remnants of previous sites/CMSes:
|
||||
{ source: "/index.xml", destination: "/feed.xml", permanent: true },
|
||||
{ source: "/feed", destination: "/feed.xml", permanent: true },
|
||||
{ source: "/rss", destination: "/feed.xml", permanent: true },
|
||||
{ source: "/blog/:path*", destination: "/notes/", permanent: true },
|
||||
{ source: "/archives/:path*", destination: "/notes/", permanent: true },
|
||||
{ source: "/resume", destination: "/static/resume.pdf", permanent: false },
|
||||
{ source: "/resume.pdf", destination: "/static/resume.pdf", permanent: false },
|
||||
|
||||
// WordPress permalinks:
|
||||
{
|
||||
source: "/2016/02/28/millenial-with-hillary-clinton",
|
||||
destination: "/notes/millenial-with-hillary-clinton/",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/2018/12/04/how-to-shrink-linux-virtual-disk-vmware",
|
||||
destination: "/notes/how-to-shrink-linux-virtual-disk-vmware/",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/2018/12/10/cool-bash-tricks-for-your-terminal-dotfiles",
|
||||
destination: "/notes/cool-bash-tricks-for-your-terminal-dotfiles/",
|
||||
permanent: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return nextConfig;
|
||||
};
|
33
package.json
33
package.json
@ -9,12 +9,13 @@
|
||||
"email": "jake@jarv.is",
|
||||
"url": "https://github.com/jakejarvis"
|
||||
},
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"dev": "next dev -H 0.0.0.0",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "eslint . --ext js,jsx,ts,tsx,md,mdx",
|
||||
"lint": "next lint",
|
||||
"postinstall": "prisma generate"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -22,8 +23,8 @@
|
||||
"@hcaptcha/react-hcaptcha": "^1.10.1",
|
||||
"@novnc/novnc": "1.4.0",
|
||||
"@octokit/graphql": "^8.0.1",
|
||||
"@octokit/graphql-schema": "^14.58.0",
|
||||
"@prisma/client": "^5.10.2",
|
||||
"@octokit/graphql-schema": "^15.3.0",
|
||||
"@prisma/client": "^5.11.0",
|
||||
"@react-spring/web": "^9.7.3",
|
||||
"@stitches/react": "1.3.1-1",
|
||||
"comma-number": "^2.1.0",
|
||||
@ -38,7 +39,7 @@
|
||||
"next": "14.1.0",
|
||||
"next-mdx-remote": "^4.4.1",
|
||||
"next-seo": "^6.5.0",
|
||||
"nodemailer": "^6.9.10",
|
||||
"nodemailer": "^6.9.12",
|
||||
"obj-str": "^1.1.0",
|
||||
"p-map": "^7.0.1",
|
||||
"p-memoize": "^7.1.1",
|
||||
@ -47,13 +48,13 @@
|
||||
"query-string": "^9.0.0",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-error-boundary": "^4.0.12",
|
||||
"react-error-boundary": "^4.0.13",
|
||||
"react-frame-component": "^5.2.6",
|
||||
"react-icons": "^5.0.1",
|
||||
"react-innertext": "^1.1.5",
|
||||
"react-intersection-observer": "^9.8.1",
|
||||
"react-is": "18.2.0",
|
||||
"react-player": "^2.14.1",
|
||||
"react-player": "^2.15.1",
|
||||
"react-textarea-autosize": "^8.5.3",
|
||||
"react-tweet": "^3.2.0",
|
||||
"rehype-prism-plus": "^2.0.0",
|
||||
@ -75,16 +76,16 @@
|
||||
"devDependencies": {
|
||||
"@jakejarvis/eslint-config": "^3.1.0",
|
||||
"@types/comma-number": "^2.1.2",
|
||||
"@types/node": "^20.11.22",
|
||||
"@types/node": "^20.11.26",
|
||||
"@types/nodemailer": "^6.4.14",
|
||||
"@types/novnc__novnc": "^1.3.4",
|
||||
"@types/prop-types": "^15.7.11",
|
||||
"@types/react": "^18.2.60",
|
||||
"@types/react-dom": "^18.2.19",
|
||||
"@types/react": "^18.2.65",
|
||||
"@types/react-dom": "^18.2.21",
|
||||
"@types/react-is": "^18.2.4",
|
||||
"@types/strip-comments": "^2.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^7.1.0",
|
||||
"@typescript-eslint/parser": "^7.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
||||
"@typescript-eslint/parser": "^7.2.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "~8.57.0",
|
||||
"eslint-config-next": "14.1.0",
|
||||
@ -93,9 +94,9 @@
|
||||
"eslint-plugin-prettier": "~5.1.3",
|
||||
"lint-staged": "^15.2.2",
|
||||
"prettier": "^3.2.5",
|
||||
"prisma": "^5.10.2",
|
||||
"simple-git-hooks": "^2.9.0",
|
||||
"typescript": "^5.3.3"
|
||||
"prisma": "^5.11.0",
|
||||
"simple-git-hooks": "^2.10.0",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"sharp": "^0.33.2"
|
||||
@ -108,10 +109,10 @@
|
||||
".next/cache"
|
||||
],
|
||||
"simple-git-hooks": {
|
||||
"pre-commit": "npx lint-staged"
|
||||
"pre-commit": "pnpm exec lint-staged"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,jsx,ts,tsx,md,mdx}": [
|
||||
"*.{js,jsx,mjs,ts,tsx,md,mdx}": [
|
||||
"eslint"
|
||||
]
|
||||
},
|
||||
|
@ -4,7 +4,7 @@ import { DefaultSeo, SocialProfileJsonLd } from "next-seo";
|
||||
import * as Fathom from "fathom-client";
|
||||
import { ThemeProvider } from "../contexts/ThemeContext";
|
||||
import Layout from "../components/Layout";
|
||||
import * as config from "../lib/config";
|
||||
import config from "../lib/config";
|
||||
import { defaultSeo, socialProfileJsonLd } from "../lib/config/seo";
|
||||
import { globalStyles, classNames } from "../lib/styles/stitches.config";
|
||||
import type { ReactElement, ReactNode } from "react";
|
||||
@ -26,6 +26,11 @@ const App = ({ Component, pageProps }: AppProps) => {
|
||||
const canonical = `${process.env.NEXT_PUBLIC_BASE_URL || ""}${router.pathname === "/" ? "" : router.pathname}/`;
|
||||
|
||||
useEffect(() => {
|
||||
// bail immediately if the site ID is not set
|
||||
if (!process.env.NEXT_PUBLIC_FATHOM_SITE_ID) {
|
||||
return;
|
||||
}
|
||||
|
||||
// don't track pageviews on branch/deploy previews and localhost
|
||||
if (process.env.NEXT_PUBLIC_VERCEL_ENV !== "production") {
|
||||
return;
|
||||
@ -33,7 +38,7 @@ const App = ({ Component, pageProps }: AppProps) => {
|
||||
|
||||
// https://usefathom.com/docs/integrations/next
|
||||
// https://vercel.com/guides/deploying-nextjs-using-fathom-analytics-with-vercel
|
||||
Fathom.load(config.fathomSiteId, {
|
||||
Fathom.load(process.env.NEXT_PUBLIC_FATHOM_SITE_ID, {
|
||||
includedDomains: [config.siteDomain],
|
||||
});
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Html, Head, Main, NextScript } from "next/document";
|
||||
import { getCssText, theme } from "../lib/styles/stitches.config";
|
||||
import * as config from "../lib/config";
|
||||
import config from "../lib/config";
|
||||
|
||||
// https://nextjs.org/docs/advanced-features/custom-document
|
||||
const Document = () => {
|
||||
|
@ -1,40 +1,47 @@
|
||||
import nodemailer from "nodemailer";
|
||||
import queryString from "query-string";
|
||||
import fetcher from "../../lib/helpers/fetcher";
|
||||
import { siteDomain, authorEmail, hcaptchaSiteKey } from "../../lib/config";
|
||||
import config from "../../lib/config";
|
||||
import type { NextApiHandler } from "next";
|
||||
|
||||
const handler: NextApiHandler = async (req, res) => {
|
||||
// redirect GET requests to this endpoint to the contact form itself
|
||||
if (req.method === "GET") {
|
||||
return res.redirect(`${process.env.NEXT_PUBLIC_BASE_URL || `https://${siteDomain}`}/contact/`);
|
||||
// only allow POST requests, otherwise return a 405 Method Not Allowed
|
||||
if (req.method !== "POST") {
|
||||
return res.status(405).send(null);
|
||||
}
|
||||
|
||||
// possible weirdness? https://github.com/orgs/vercel/discussions/78#discussioncomment-5089059
|
||||
const data = req.body;
|
||||
try {
|
||||
// possible weirdness? https://github.com/orgs/vercel/discussions/78#discussioncomment-5089059
|
||||
const data = req.body;
|
||||
|
||||
// these are both backups to client-side validations just in case someone squeezes through without them. the codes
|
||||
// are identical so they're caught in the same fashion.
|
||||
if (!data.name || !data.email || !data.message) {
|
||||
// all fields are required
|
||||
throw new Error("MISSING_DATA");
|
||||
// these are both backups to client-side validations just in case someone squeezes through without them. the codes
|
||||
// are identical so they're caught in the same fashion.
|
||||
if (!data.name || !data.email || !data.message) {
|
||||
// all fields are required
|
||||
throw new Error("missing_data");
|
||||
}
|
||||
if (!data["h-captcha-response"] || !(await validateCaptcha(data["h-captcha-response"]))) {
|
||||
// either the captcha is wrong or completely missing
|
||||
throw new Error("invalid_captcha");
|
||||
}
|
||||
|
||||
// throw an internal error, not user's fault
|
||||
if (!(await sendMessage(data))) {
|
||||
throw new Error("nodemailer_error");
|
||||
}
|
||||
|
||||
// disable caching on both ends. see:
|
||||
// https://vercel.com/docs/concepts/functions/edge-functions/edge-caching
|
||||
res.setHeader("Cache-Control", "private, no-cache, no-store, must-revalidate");
|
||||
|
||||
// success! let the client know
|
||||
return res.status(201).json({ success: true });
|
||||
} catch (
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
error: any
|
||||
) {
|
||||
return res.status(400).json({ error: error.message ?? "Bad request." });
|
||||
}
|
||||
if (!data["h-captcha-response"] || !(await validateCaptcha(data["h-captcha-response"]))) {
|
||||
// either the captcha is wrong or completely missing
|
||||
throw new Error("INVALID_CAPTCHA");
|
||||
}
|
||||
|
||||
// throw an internal error, not user's fault
|
||||
if (!(await sendMessage(data))) {
|
||||
throw new Error("NODEMAILER_ERROR");
|
||||
}
|
||||
|
||||
// disable caching on both ends. see:
|
||||
// https://vercel.com/docs/concepts/functions/edge-functions/edge-caching
|
||||
res.setHeader("Cache-Control", "private, no-cache, no-store, must-revalidate");
|
||||
|
||||
// success! let the client know
|
||||
return res.status(201).json({ success: true });
|
||||
};
|
||||
|
||||
const validateCaptcha = async (formResponse: unknown): Promise<unknown> => {
|
||||
@ -46,7 +53,7 @@ const validateCaptcha = async (formResponse: unknown): Promise<unknown> => {
|
||||
body: queryString.stringify({
|
||||
response: formResponse,
|
||||
// fallback to dummy secret for testing: https://docs.hcaptcha.com/#integration-testing-test-keys
|
||||
sitekey: hcaptchaSiteKey || "10000000-ffff-ffff-ffff-000000000001",
|
||||
sitekey: process.env.NEXT_PUBLIC_HCAPTCHA_SITE_KEY || "10000000-ffff-ffff-ffff-000000000001",
|
||||
secret: process.env.HCAPTCHA_SECRET_KEY || "0x0000000000000000000000000000000000000000",
|
||||
}),
|
||||
});
|
||||
@ -57,19 +64,22 @@ const validateCaptcha = async (formResponse: unknown): Promise<unknown> => {
|
||||
const sendMessage = async (data: Record<string, unknown>): Promise<boolean> => {
|
||||
try {
|
||||
const transporter = nodemailer.createTransport({
|
||||
service: "mailgun",
|
||||
// https://resend.com/docs/send-with-nodemailer-smtp
|
||||
host: "smtp.resend.com",
|
||||
secure: true,
|
||||
port: 465,
|
||||
auth: {
|
||||
user: process.env.MAILGUN_SMTP_USER,
|
||||
pass: process.env.MAILGUN_SMTP_PASS,
|
||||
user: "resend",
|
||||
pass: process.env.RESEND_API_KEY,
|
||||
},
|
||||
});
|
||||
|
||||
await transporter.sendMail({
|
||||
from: `${data.name} <${process.env.MAILGUN_SMTP_USER}>`,
|
||||
sender: `nodemailer <${process.env.MAILGUN_SMTP_USER}>`,
|
||||
from: `${data.name} <${process.env.RESEND_DOMAIN ? `noreply@${process.env.RESEND_DOMAIN}` : "onboarding@resend.dev"}>`,
|
||||
sender: `nodemailer <${process.env.RESEND_DOMAIN ? `noreply@${process.env.RESEND_DOMAIN}` : "onboarding@resend.dev"}>`,
|
||||
replyTo: `${data.name} <${data.email}>`,
|
||||
to: `<${authorEmail}>`,
|
||||
subject: `[${siteDomain}] Contact Form Submission`,
|
||||
to: `<${config.authorEmail}>`,
|
||||
subject: `[${config.siteDomain}] Contact Form Submission`,
|
||||
// TODO: add markdown parsing as promised on the form.
|
||||
text: `${data.message}`,
|
||||
});
|
||||
|
@ -2,7 +2,7 @@ import { buildFeed } from "../lib/helpers/build-feed";
|
||||
import type { GetServerSideFeedProps } from "../lib/helpers/build-feed";
|
||||
|
||||
export const getServerSideProps: GetServerSideFeedProps = async (context) => {
|
||||
return buildFeed(context, "atom");
|
||||
return buildFeed(context, { format: "atom" });
|
||||
};
|
||||
|
||||
// eslint-disable-next-line import/no-anonymous-default-export
|
||||
|
@ -2,7 +2,7 @@ import { buildFeed } from "../lib/helpers/build-feed";
|
||||
import type { GetServerSideFeedProps } from "../lib/helpers/build-feed";
|
||||
|
||||
export const getServerSideProps: GetServerSideFeedProps = async (context) => {
|
||||
return buildFeed(context, "rss");
|
||||
return buildFeed(context, { format: "rss" });
|
||||
};
|
||||
|
||||
// eslint-disable-next-line import/no-anonymous-default-export
|
||||
|
@ -6,7 +6,7 @@ import PostMeta from "../../components/PostMeta";
|
||||
import Comments from "../../components/Comments";
|
||||
import * as mdxComponents from "../../lib/helpers/mdx-components";
|
||||
import { getPostSlugs, compilePost } from "../../lib/helpers/posts";
|
||||
import * as config from "../../lib/config";
|
||||
import config from "../../lib/config";
|
||||
import { articleJsonLd } from "../../lib/config/seo";
|
||||
import { meJpg } from "../../lib/config/favicons";
|
||||
import type { GetStaticProps, GetStaticPaths, InferGetStaticPropsType } from "next";
|
||||
|
@ -2,7 +2,7 @@ import { NextSeo } from "next-seo";
|
||||
import Content from "../../components/Content";
|
||||
import PostsList from "../../components/PostsList";
|
||||
import { getAllPosts } from "../../lib/helpers/posts";
|
||||
import { authorName } from "../../lib/config";
|
||||
import config from "../../lib/config";
|
||||
import type { GetStaticProps, InferGetStaticPropsType } from "next";
|
||||
import type { PostsByYear } from "../../types";
|
||||
|
||||
@ -11,7 +11,7 @@ const Notes = ({ notesByYear }: InferGetStaticPropsType<typeof getStaticProps>)
|
||||
<>
|
||||
<NextSeo
|
||||
title="Notes"
|
||||
description={`Recent posts by ${authorName}.`}
|
||||
description={`Recent posts by ${config.authorName}.`}
|
||||
openGraph={{
|
||||
title: "Notes",
|
||||
}}
|
||||
|
@ -6,7 +6,7 @@ import Link from "../components/Link";
|
||||
import RepositoryCard from "../components/RepositoryCard";
|
||||
import { SiGithub } from "react-icons/si";
|
||||
import { styled, theme } from "../lib/styles/stitches.config";
|
||||
import { authorSocial } from "../lib/config";
|
||||
import config from "../lib/config";
|
||||
import type { GetStaticProps, InferGetStaticPropsType } from "next";
|
||||
import type { User, Repository } from "@octokit/graphql-schema";
|
||||
import type { Project } from "../types";
|
||||
@ -60,7 +60,7 @@ const Projects = ({ repos }: InferGetStaticPropsType<typeof getStaticProps>) =>
|
||||
</Wrapper>
|
||||
|
||||
<ViewMore>
|
||||
<Link href={`https://github.com/${authorSocial.github}`}>
|
||||
<Link href={`https://github.com/${config.authorSocial.github}`}>
|
||||
View more on <GitHubLogo /> GitHub...
|
||||
</Link>
|
||||
</ViewMore>
|
||||
@ -73,7 +73,7 @@ export const getStaticProps: GetStaticProps<{
|
||||
repos: Project[];
|
||||
}> = async () => {
|
||||
// don't fail the entire site build if the required API key for this page is missing
|
||||
if (typeof process.env.GH_PUBLIC_TOKEN === "undefined" || process.env.GH_PUBLIC_TOKEN === "") {
|
||||
if (!process.env.GH_PUBLIC_TOKEN || process.env.GH_PUBLIC_TOKEN === "") {
|
||||
console.warn(`ERROR: I can't fetch any GitHub projects without "GH_PUBLIC_TOKEN" set! Skipping for now...`);
|
||||
|
||||
return {
|
||||
@ -113,7 +113,7 @@ export const getStaticProps: GetStaticProps<{
|
||||
}
|
||||
`,
|
||||
{
|
||||
username: authorSocial.github,
|
||||
username: config.authorSocial.github,
|
||||
sort: "STARGAZERS",
|
||||
limit: 12,
|
||||
headers: {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import * as config from "../lib/config";
|
||||
import config from "../lib/config";
|
||||
import { chrome512Png, chrome192Png, maskable512Png, maskable192Png } from "../lib/config/favicons";
|
||||
import type { GetServerSideProps } from "next";
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { SitemapStream, EnumChangefreq } from "sitemap";
|
||||
import { getAllPosts } from "../lib/helpers/posts";
|
||||
import { siteDomain } from "../lib/config";
|
||||
import config from "../lib/config";
|
||||
import type { GetServerSideProps } from "next";
|
||||
import type { SitemapItemLoose } from "sitemap";
|
||||
|
||||
export const getServerSideProps: GetServerSideProps<Record<string, never>> = async (context) => {
|
||||
const { res } = context;
|
||||
const stream = new SitemapStream({ hostname: process.env.NEXT_PUBLIC_BASE_URL || `https://${siteDomain}` });
|
||||
const stream = new SitemapStream({ hostname: process.env.NEXT_PUBLIC_BASE_URL || `https://${config.siteDomain}` });
|
||||
|
||||
// cache on edge for 12 hours
|
||||
res.setHeader("cache-control", "public, max-age=0, s-maxage=43200, stale-while-revalidate");
|
||||
|
298
pnpm-lock.yaml
generated
298
pnpm-lock.yaml
generated
@ -18,11 +18,11 @@ dependencies:
|
||||
specifier: ^8.0.1
|
||||
version: 8.0.1
|
||||
'@octokit/graphql-schema':
|
||||
specifier: ^14.58.0
|
||||
version: 14.58.0
|
||||
specifier: ^15.3.0
|
||||
version: 15.3.0
|
||||
'@prisma/client':
|
||||
specifier: ^5.10.2
|
||||
version: 5.10.2(prisma@5.10.2)
|
||||
specifier: ^5.11.0
|
||||
version: 5.11.0(prisma@5.11.0)
|
||||
'@react-spring/web':
|
||||
specifier: ^9.7.3
|
||||
version: 9.7.3(react-dom@18.2.0)(react@18.2.0)
|
||||
@ -66,8 +66,8 @@ dependencies:
|
||||
specifier: ^6.5.0
|
||||
version: 6.5.0(next@14.1.0)(react-dom@18.2.0)(react@18.2.0)
|
||||
nodemailer:
|
||||
specifier: ^6.9.10
|
||||
version: 6.9.10
|
||||
specifier: ^6.9.12
|
||||
version: 6.9.12
|
||||
obj-str:
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.0
|
||||
@ -93,8 +93,8 @@ dependencies:
|
||||
specifier: 18.2.0
|
||||
version: 18.2.0(react@18.2.0)
|
||||
react-error-boundary:
|
||||
specifier: ^4.0.12
|
||||
version: 4.0.12(react@18.2.0)
|
||||
specifier: ^4.0.13
|
||||
version: 4.0.13(react@18.2.0)
|
||||
react-frame-component:
|
||||
specifier: ^5.2.6
|
||||
version: 5.2.6(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
@ -103,7 +103,7 @@ dependencies:
|
||||
version: 5.0.1(react@18.2.0)
|
||||
react-innertext:
|
||||
specifier: ^1.1.5
|
||||
version: 1.1.5(@types/react@18.2.60)(react@18.2.0)
|
||||
version: 1.1.5(@types/react@18.2.65)(react@18.2.0)
|
||||
react-intersection-observer:
|
||||
specifier: ^9.8.1
|
||||
version: 9.8.1(react-dom@18.2.0)(react@18.2.0)
|
||||
@ -111,11 +111,11 @@ dependencies:
|
||||
specifier: 18.2.0
|
||||
version: 18.2.0
|
||||
react-player:
|
||||
specifier: ^2.14.1
|
||||
version: 2.14.1(react@18.2.0)
|
||||
specifier: ^2.15.1
|
||||
version: 2.15.1(react@18.2.0)
|
||||
react-textarea-autosize:
|
||||
specifier: ^8.5.3
|
||||
version: 8.5.3(@types/react@18.2.60)(react@18.2.0)
|
||||
version: 8.5.3(@types/react@18.2.65)(react@18.2.0)
|
||||
react-tweet:
|
||||
specifier: ^3.2.0
|
||||
version: 3.2.0(react-dom@18.2.0)(react@18.2.0)
|
||||
@ -178,8 +178,8 @@ devDependencies:
|
||||
specifier: ^2.1.2
|
||||
version: 2.1.2
|
||||
'@types/node':
|
||||
specifier: ^20.11.22
|
||||
version: 20.11.22
|
||||
specifier: ^20.11.26
|
||||
version: 20.11.26
|
||||
'@types/nodemailer':
|
||||
specifier: ^6.4.14
|
||||
version: 6.4.14
|
||||
@ -190,11 +190,11 @@ devDependencies:
|
||||
specifier: ^15.7.11
|
||||
version: 15.7.11
|
||||
'@types/react':
|
||||
specifier: ^18.2.60
|
||||
version: 18.2.60
|
||||
specifier: ^18.2.65
|
||||
version: 18.2.65
|
||||
'@types/react-dom':
|
||||
specifier: ^18.2.19
|
||||
version: 18.2.19
|
||||
specifier: ^18.2.21
|
||||
version: 18.2.21
|
||||
'@types/react-is':
|
||||
specifier: ^18.2.4
|
||||
version: 18.2.4
|
||||
@ -202,11 +202,11 @@ devDependencies:
|
||||
specifier: ^2.0.4
|
||||
version: 2.0.4
|
||||
'@typescript-eslint/eslint-plugin':
|
||||
specifier: ^7.1.0
|
||||
version: 7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3)
|
||||
specifier: ^7.2.0
|
||||
version: 7.2.0(@typescript-eslint/parser@7.2.0)(eslint@8.57.0)(typescript@5.4.2)
|
||||
'@typescript-eslint/parser':
|
||||
specifier: ^7.1.0
|
||||
version: 7.1.0(eslint@8.57.0)(typescript@5.3.3)
|
||||
specifier: ^7.2.0
|
||||
version: 7.2.0(eslint@8.57.0)(typescript@5.4.2)
|
||||
cross-env:
|
||||
specifier: ^7.0.3
|
||||
version: 7.0.3
|
||||
@ -215,7 +215,7 @@ devDependencies:
|
||||
version: 8.57.0
|
||||
eslint-config-next:
|
||||
specifier: 14.1.0
|
||||
version: 14.1.0(eslint@8.57.0)(typescript@5.3.3)
|
||||
version: 14.1.0(eslint@8.57.0)(typescript@5.4.2)
|
||||
eslint-config-prettier:
|
||||
specifier: ~9.1.0
|
||||
version: 9.1.0(eslint@8.57.0)
|
||||
@ -232,14 +232,14 @@ devDependencies:
|
||||
specifier: ^3.2.5
|
||||
version: 3.2.5
|
||||
prisma:
|
||||
specifier: ^5.10.2
|
||||
version: 5.10.2
|
||||
specifier: ^5.11.0
|
||||
version: 5.11.0
|
||||
simple-git-hooks:
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0
|
||||
specifier: ^2.10.0
|
||||
version: 2.10.0
|
||||
typescript:
|
||||
specifier: ^5.3.3
|
||||
version: 5.3.3
|
||||
specifier: ^5.4.2
|
||||
version: 5.4.2
|
||||
|
||||
packages:
|
||||
|
||||
@ -616,7 +616,7 @@ packages:
|
||||
react: '>=16'
|
||||
dependencies:
|
||||
'@types/mdx': 2.0.8
|
||||
'@types/react': 18.2.60
|
||||
'@types/react': 18.2.65
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
@ -770,8 +770,8 @@ packages:
|
||||
universal-user-agent: 7.0.2
|
||||
dev: false
|
||||
|
||||
/@octokit/graphql-schema@14.58.0:
|
||||
resolution: {integrity: sha512-89QSUV1Dgxzq90wqkv0Nmw7jHfFCAQ4K/fjp5ezvDEHqFFzMCn25TBQlm38WB8ams+hGxInRDbITCP0n7GTGlg==}
|
||||
/@octokit/graphql-schema@15.3.0:
|
||||
resolution: {integrity: sha512-yGj0haNZY1/4DZO72KpJdOzvKQFYPUkD5d6PdntPSbekABUoOdStAtEsOtuwZz52cPrbQEEoZ0wN7aemA1y8PA==}
|
||||
dependencies:
|
||||
graphql: 16.8.1
|
||||
graphql-tag: 2.12.6(graphql@16.8.1)
|
||||
@ -825,8 +825,8 @@ packages:
|
||||
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
|
||||
dev: true
|
||||
|
||||
/@prisma/client@5.10.2(prisma@5.10.2):
|
||||
resolution: {integrity: sha512-ef49hzB2yJZCvM5gFHMxSFL9KYrIP9udpT5rYo0CsHD4P9IKj473MbhU1gjKKftiwWBTIyrt9jukprzZXazyag==}
|
||||
/@prisma/client@5.11.0(prisma@5.11.0):
|
||||
resolution: {integrity: sha512-SWshvS5FDXvgJKM/a0y9nDC1rqd7KG0Q6ZVzd+U7ZXK5soe73DJxJJgbNBt2GNXOa+ysWB4suTpdK5zfFPhwiw==}
|
||||
engines: {node: '>=16.13'}
|
||||
requiresBuild: true
|
||||
peerDependencies:
|
||||
@ -835,35 +835,35 @@ packages:
|
||||
prisma:
|
||||
optional: true
|
||||
dependencies:
|
||||
prisma: 5.10.2
|
||||
prisma: 5.11.0
|
||||
dev: false
|
||||
|
||||
/@prisma/debug@5.10.2:
|
||||
resolution: {integrity: sha512-bkBOmH9dpEBbMKFJj8V+Zp8IZHIBjy3fSyhLhxj4FmKGb/UBSt9doyfA6k1UeUREsMJft7xgPYBbHSOYBr8XCA==}
|
||||
/@prisma/debug@5.11.0:
|
||||
resolution: {integrity: sha512-N6yYr3AbQqaiUg+OgjkdPp3KPW1vMTAgtKX6+BiB/qB2i1TjLYCrweKcUjzOoRM5BriA4idrkTej9A9QqTfl3A==}
|
||||
|
||||
/@prisma/engines-version@5.10.0-34.5a9203d0590c951969e85a7d07215503f4672eb9:
|
||||
resolution: {integrity: sha512-uCy/++3Jx/O3ufM+qv2H1L4tOemTNqcP/gyEVOlZqTpBvYJUe0tWtW0y3o2Ueq04mll4aM5X3f6ugQftOSLdFQ==}
|
||||
/@prisma/engines-version@5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102:
|
||||
resolution: {integrity: sha512-WXCuyoymvrS4zLz4wQagSsc3/nE6CHy8znyiMv8RKazKymOMd5o9FP5RGwGHAtgoxd+aB/BWqxuP/Ckfu7/3MA==}
|
||||
|
||||
/@prisma/engines@5.10.2:
|
||||
resolution: {integrity: sha512-HkSJvix6PW8YqEEt3zHfCYYJY69CXsNdhU+wna+4Y7EZ+AwzeupMnUThmvaDA7uqswiHkgm5/SZ6/4CStjaGmw==}
|
||||
/@prisma/engines@5.11.0:
|
||||
resolution: {integrity: sha512-gbrpQoBTYWXDRqD+iTYMirDlF9MMlQdxskQXbhARhG6A/uFQjB7DZMYocMQLoiZXO/IskfDOZpPoZE8TBQKtEw==}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
'@prisma/debug': 5.10.2
|
||||
'@prisma/engines-version': 5.10.0-34.5a9203d0590c951969e85a7d07215503f4672eb9
|
||||
'@prisma/fetch-engine': 5.10.2
|
||||
'@prisma/get-platform': 5.10.2
|
||||
'@prisma/debug': 5.11.0
|
||||
'@prisma/engines-version': 5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102
|
||||
'@prisma/fetch-engine': 5.11.0
|
||||
'@prisma/get-platform': 5.11.0
|
||||
|
||||
/@prisma/fetch-engine@5.10.2:
|
||||
resolution: {integrity: sha512-dSmXcqSt6DpTmMaLQ9K8ZKzVAMH3qwGCmYEZr/uVnzVhxRJ1EbT/w2MMwIdBNq1zT69Rvh0h75WMIi0mrIw7Hg==}
|
||||
/@prisma/fetch-engine@5.11.0:
|
||||
resolution: {integrity: sha512-994viazmHTJ1ymzvWugXod7dZ42T2ROeFuH6zHPcUfp/69+6cl5r9u3NFb6bW8lLdNjwLYEVPeu3hWzxpZeC0w==}
|
||||
dependencies:
|
||||
'@prisma/debug': 5.10.2
|
||||
'@prisma/engines-version': 5.10.0-34.5a9203d0590c951969e85a7d07215503f4672eb9
|
||||
'@prisma/get-platform': 5.10.2
|
||||
'@prisma/debug': 5.11.0
|
||||
'@prisma/engines-version': 5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102
|
||||
'@prisma/get-platform': 5.11.0
|
||||
|
||||
/@prisma/get-platform@5.10.2:
|
||||
resolution: {integrity: sha512-nqXP6vHiY2PIsebBAuDeWiUYg8h8mfjBckHh6Jezuwej0QJNnjDiOq30uesmg+JXxGk99nqyG3B7wpcOODzXvg==}
|
||||
/@prisma/get-platform@5.11.0:
|
||||
resolution: {integrity: sha512-rxtHpMLxNTHxqWuGOLzR2QOyQi79rK1u1XYAVLZxDGTLz/A+uoDnjz9veBFlicrpWjwuieM4N6jcnjj/DDoidw==}
|
||||
dependencies:
|
||||
'@prisma/debug': 5.10.2
|
||||
'@prisma/debug': 5.11.0
|
||||
|
||||
/@react-spring/animated@9.7.3(react@18.2.0):
|
||||
resolution: {integrity: sha512-5CWeNJt9pNgyvuSzQH+uy2pvTg8Y4/OisoscZIR8/ZNLIOI+CatFBhGZpDGTF/OzdNFsAoGk3wiUYTwoJ0YIvw==}
|
||||
@ -949,7 +949,7 @@ packages:
|
||||
/@types/concat-stream@2.0.0:
|
||||
resolution: {integrity: sha512-t3YCerNM7NTVjLuICZo5gYAXYoDvpuuTceCcFQWcDQz26kxUR5uIWolxbIR5jRNIXpMqhOpW/b8imCR1LEmuJw==}
|
||||
dependencies:
|
||||
'@types/node': 20.11.22
|
||||
'@types/node': 20.11.26
|
||||
dev: true
|
||||
|
||||
/@types/debug@4.1.12:
|
||||
@ -979,7 +979,7 @@ packages:
|
||||
/@types/hoist-non-react-statics@3.3.2:
|
||||
resolution: {integrity: sha512-YIQtIg4PKr7ZyqNPZObpxfHsHEmuB8dXCxd6qVcGuQVDK2bpsF7bYNnBJ4Nn7giuACZg+WewExgrtAJ3XnA4Xw==}
|
||||
dependencies:
|
||||
'@types/react': 18.2.60
|
||||
'@types/react': 18.2.65
|
||||
hoist-non-react-statics: 3.3.2
|
||||
dev: false
|
||||
|
||||
@ -1026,15 +1026,15 @@ packages:
|
||||
resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==}
|
||||
dev: false
|
||||
|
||||
/@types/node@20.11.22:
|
||||
resolution: {integrity: sha512-/G+IxWxma6V3E+pqK1tSl2Fo1kl41pK1yeCyDsgkF9WlVAme4j5ISYM2zR11bgLFJGLN5sVK40T4RJNuiZbEjA==}
|
||||
/@types/node@20.11.26:
|
||||
resolution: {integrity: sha512-YwOMmyhNnAWijOBQweOJnQPl068Oqd4K3OFbTc6AHJwzweUwwWG3GIFY74OKks2PJUDkQPeddOQES9mLn1CTEQ==}
|
||||
dependencies:
|
||||
undici-types: 5.26.5
|
||||
|
||||
/@types/nodemailer@6.4.14:
|
||||
resolution: {integrity: sha512-fUWthHO9k9DSdPCSPRqcu6TWhYyxTBg382vlNIttSe9M7XfsT06y0f24KHXtbnijPGGRIcVvdKHTNikOI6qiHA==}
|
||||
dependencies:
|
||||
'@types/node': 20.11.22
|
||||
'@types/node': 20.11.26
|
||||
dev: true
|
||||
|
||||
/@types/novnc__novnc@1.3.4:
|
||||
@ -1048,20 +1048,20 @@ packages:
|
||||
/@types/prop-types@15.7.11:
|
||||
resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==}
|
||||
|
||||
/@types/react-dom@18.2.19:
|
||||
resolution: {integrity: sha512-aZvQL6uUbIJpjZk4U8JZGbau9KDeAwMfmhyWorxgBkqDIEf6ROjRozcmPIicqsUwPUjbkDfHKgGee1Lq65APcA==}
|
||||
/@types/react-dom@18.2.21:
|
||||
resolution: {integrity: sha512-gnvBA/21SA4xxqNXEwNiVcP0xSGHh/gi1VhWv9Bl46a0ItbTT5nFY+G9VSQpaG/8N/qdJpJ+vftQ4zflTtnjLw==}
|
||||
dependencies:
|
||||
'@types/react': 18.2.60
|
||||
'@types/react': 18.2.65
|
||||
dev: true
|
||||
|
||||
/@types/react-is@18.2.4:
|
||||
resolution: {integrity: sha512-wBc7HgmbCcrvw0fZjxbgz/xrrlZKzEqmABBMeSvpTvdm25u6KI6xdIi9pRE2G0C1Lw5ETFdcn4UbYZ4/rpqUYw==}
|
||||
dependencies:
|
||||
'@types/react': 18.2.60
|
||||
'@types/react': 18.2.65
|
||||
dev: true
|
||||
|
||||
/@types/react@18.2.60:
|
||||
resolution: {integrity: sha512-dfiPj9+k20jJrLGOu9Nf6eqxm2EyJRrq2NvwOFsfbb7sFExZ9WELPs67UImHj3Ayxg8ruTtKtNnbjaF8olPq0A==}
|
||||
/@types/react@18.2.65:
|
||||
resolution: {integrity: sha512-98TsY0aW4jqx/3RqsUXwMDZSWR1Z4CUlJNue8ueS2/wcxZOsz4xmW1X8ieaWVRHcmmQM3R8xVA4XWB3dJnWwDQ==}
|
||||
dependencies:
|
||||
'@types/prop-types': 15.7.11
|
||||
'@types/scheduler': 0.16.4
|
||||
@ -1070,7 +1070,7 @@ packages:
|
||||
/@types/sax@1.2.5:
|
||||
resolution: {integrity: sha512-9jWta97bBVC027/MShr3gLab8gPhKy4l6qpb+UJLF5pDm3501NvA7uvqVCW+REFtx00oTi6Cq9JzLwgq6evVgw==}
|
||||
dependencies:
|
||||
'@types/node': 20.11.22
|
||||
'@types/node': 20.11.26
|
||||
dev: false
|
||||
|
||||
/@types/scheduler@0.16.4:
|
||||
@ -1098,8 +1098,8 @@ packages:
|
||||
/@types/unist@3.0.2:
|
||||
resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==}
|
||||
|
||||
/@typescript-eslint/eslint-plugin@7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-j6vT/kCulhG5wBmGtstKeiVr1rdXE4nk+DT1k6trYkwlrvW9eOF5ZbgKnd/YR6PcM4uTEXa0h6Fcvf6X7Dxl0w==}
|
||||
/@typescript-eslint/eslint-plugin@7.2.0(@typescript-eslint/parser@7.2.0)(eslint@8.57.0)(typescript@5.4.2):
|
||||
resolution: {integrity: sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
'@typescript-eslint/parser': ^7.0.0
|
||||
@ -1110,24 +1110,24 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.10.0
|
||||
'@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/scope-manager': 7.1.0
|
||||
'@typescript-eslint/type-utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/visitor-keys': 7.1.0
|
||||
'@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.4.2)
|
||||
'@typescript-eslint/scope-manager': 7.2.0
|
||||
'@typescript-eslint/type-utils': 7.2.0(eslint@8.57.0)(typescript@5.4.2)
|
||||
'@typescript-eslint/utils': 7.2.0(eslint@8.57.0)(typescript@5.4.2)
|
||||
'@typescript-eslint/visitor-keys': 7.2.0
|
||||
debug: 4.3.4
|
||||
eslint: 8.57.0
|
||||
graphemer: 1.4.0
|
||||
ignore: 5.3.0
|
||||
natural-compare: 1.4.0
|
||||
semver: 7.5.4
|
||||
ts-api-utils: 1.0.3(typescript@5.3.3)
|
||||
typescript: 5.3.3
|
||||
ts-api-utils: 1.0.3(typescript@5.4.2)
|
||||
typescript: 5.4.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.3.3):
|
||||
/@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.2):
|
||||
resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
@ -1139,17 +1139,17 @@ packages:
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 6.21.0
|
||||
'@typescript-eslint/types': 6.21.0
|
||||
'@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3)
|
||||
'@typescript-eslint/typescript-estree': 6.21.0(typescript@5.4.2)
|
||||
'@typescript-eslint/visitor-keys': 6.21.0
|
||||
debug: 4.3.4
|
||||
eslint: 8.57.0
|
||||
typescript: 5.3.3
|
||||
typescript: 5.4.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-V1EknKUubZ1gWFjiOZhDSNToOjs63/9O0puCgGS8aDOgpZY326fzFu15QAUjwaXzRZjf/qdsdBrckYdv9YxB8w==}
|
||||
/@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.2):
|
||||
resolution: {integrity: sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.56.0
|
||||
@ -1158,13 +1158,13 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 7.1.0
|
||||
'@typescript-eslint/types': 7.1.0
|
||||
'@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3)
|
||||
'@typescript-eslint/visitor-keys': 7.1.0
|
||||
'@typescript-eslint/scope-manager': 7.2.0
|
||||
'@typescript-eslint/types': 7.2.0
|
||||
'@typescript-eslint/typescript-estree': 7.2.0(typescript@5.4.2)
|
||||
'@typescript-eslint/visitor-keys': 7.2.0
|
||||
debug: 4.3.4
|
||||
eslint: 8.57.0
|
||||
typescript: 5.3.3
|
||||
typescript: 5.4.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@ -1177,16 +1177,16 @@ packages:
|
||||
'@typescript-eslint/visitor-keys': 6.21.0
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/scope-manager@7.1.0:
|
||||
resolution: {integrity: sha512-6TmN4OJiohHfoOdGZ3huuLhpiUgOGTpgXNUPJgeZOZR3DnIpdSgtt83RS35OYNNXxM4TScVlpVKC9jyQSETR1A==}
|
||||
/@typescript-eslint/scope-manager@7.2.0:
|
||||
resolution: {integrity: sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 7.1.0
|
||||
'@typescript-eslint/visitor-keys': 7.1.0
|
||||
'@typescript-eslint/types': 7.2.0
|
||||
'@typescript-eslint/visitor-keys': 7.2.0
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/type-utils@7.1.0(eslint@8.57.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-UZIhv8G+5b5skkcuhgvxYWHjk7FW7/JP5lPASMEUoliAPwIH/rxoUSQPia2cuOj9AmDZmwUl1usKm85t5VUMew==}
|
||||
/@typescript-eslint/type-utils@7.2.0(eslint@8.57.0)(typescript@5.4.2):
|
||||
resolution: {integrity: sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.56.0
|
||||
@ -1195,12 +1195,12 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3)
|
||||
'@typescript-eslint/utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/typescript-estree': 7.2.0(typescript@5.4.2)
|
||||
'@typescript-eslint/utils': 7.2.0(eslint@8.57.0)(typescript@5.4.2)
|
||||
debug: 4.3.4
|
||||
eslint: 8.57.0
|
||||
ts-api-utils: 1.0.3(typescript@5.3.3)
|
||||
typescript: 5.3.3
|
||||
ts-api-utils: 1.0.3(typescript@5.4.2)
|
||||
typescript: 5.4.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@ -1210,12 +1210,12 @@ packages:
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/types@7.1.0:
|
||||
resolution: {integrity: sha512-qTWjWieJ1tRJkxgZYXx6WUYtWlBc48YRxgY2JN1aGeVpkhmnopq+SUC8UEVGNXIvWH7XyuTjwALfG6bFEgCkQA==}
|
||||
/@typescript-eslint/types@7.2.0:
|
||||
resolution: {integrity: sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/typescript-estree@6.21.0(typescript@5.3.3):
|
||||
/@typescript-eslint/typescript-estree@6.21.0(typescript@5.4.2):
|
||||
resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
@ -1231,14 +1231,14 @@ packages:
|
||||
is-glob: 4.0.3
|
||||
minimatch: 9.0.3
|
||||
semver: 7.5.4
|
||||
ts-api-utils: 1.0.3(typescript@5.3.3)
|
||||
typescript: 5.3.3
|
||||
ts-api-utils: 1.0.3(typescript@5.4.2)
|
||||
typescript: 5.4.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/typescript-estree@7.1.0(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-k7MyrbD6E463CBbSpcOnwa8oXRdHzH1WiVzOipK3L5KSML92ZKgUBrTlehdi7PEIMT8k0bQixHUGXggPAlKnOQ==}
|
||||
/@typescript-eslint/typescript-estree@7.2.0(typescript@5.4.2):
|
||||
resolution: {integrity: sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
typescript: '*'
|
||||
@ -1246,21 +1246,21 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 7.1.0
|
||||
'@typescript-eslint/visitor-keys': 7.1.0
|
||||
'@typescript-eslint/types': 7.2.0
|
||||
'@typescript-eslint/visitor-keys': 7.2.0
|
||||
debug: 4.3.4
|
||||
globby: 11.1.0
|
||||
is-glob: 4.0.3
|
||||
minimatch: 9.0.3
|
||||
semver: 7.5.4
|
||||
ts-api-utils: 1.0.3(typescript@5.3.3)
|
||||
typescript: 5.3.3
|
||||
ts-api-utils: 1.0.3(typescript@5.4.2)
|
||||
typescript: 5.4.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/utils@7.1.0(eslint@8.57.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-WUFba6PZC5OCGEmbweGpnNJytJiLG7ZvDBJJoUcX4qZYf1mGZ97mO2Mps6O2efxJcJdRNpqweCistDbZMwIVHw==}
|
||||
/@typescript-eslint/utils@7.2.0(eslint@8.57.0)(typescript@5.4.2):
|
||||
resolution: {integrity: sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.56.0
|
||||
@ -1268,9 +1268,9 @@ packages:
|
||||
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
|
||||
'@types/json-schema': 7.0.15
|
||||
'@types/semver': 7.5.6
|
||||
'@typescript-eslint/scope-manager': 7.1.0
|
||||
'@typescript-eslint/types': 7.1.0
|
||||
'@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3)
|
||||
'@typescript-eslint/scope-manager': 7.2.0
|
||||
'@typescript-eslint/types': 7.2.0
|
||||
'@typescript-eslint/typescript-estree': 7.2.0(typescript@5.4.2)
|
||||
eslint: 8.57.0
|
||||
semver: 7.5.4
|
||||
transitivePeerDependencies:
|
||||
@ -1286,11 +1286,11 @@ packages:
|
||||
eslint-visitor-keys: 3.4.3
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/visitor-keys@7.1.0:
|
||||
resolution: {integrity: sha512-FhUqNWluiGNzlvnDZiXad4mZRhtghdoKW6e98GoEOYSu5cND+E39rG5KwJMUzeENwm1ztYBRqof8wMLP+wNPIA==}
|
||||
/@typescript-eslint/visitor-keys@7.2.0:
|
||||
resolution: {integrity: sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 7.1.0
|
||||
'@typescript-eslint/types': 7.2.0
|
||||
eslint-visitor-keys: 3.4.3
|
||||
dev: true
|
||||
|
||||
@ -1975,7 +1975,7 @@ packages:
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/eslint-config-next@14.1.0(eslint@8.57.0)(typescript@5.3.3):
|
||||
/eslint-config-next@14.1.0(eslint@8.57.0)(typescript@5.4.2):
|
||||
resolution: {integrity: sha512-SBX2ed7DoRFXC6CQSLc/SbLY9Ut6HxNB2wPTcoIWjUMd7aF7O/SIE7111L8FdZ9TXsNV4pulUDnfthpyPtbFUg==}
|
||||
peerDependencies:
|
||||
eslint: ^7.23.0 || ^8.0.0
|
||||
@ -1986,15 +1986,15 @@ packages:
|
||||
dependencies:
|
||||
'@next/eslint-plugin-next': 14.1.0
|
||||
'@rushstack/eslint-patch': 1.5.1
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.2)
|
||||
eslint: 8.57.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.28.1)(eslint@8.57.0)
|
||||
eslint-plugin-import: 2.28.1(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)
|
||||
eslint-plugin-import: 2.28.1(@typescript-eslint/parser@7.2.0)(eslint@8.57.0)
|
||||
eslint-plugin-jsx-a11y: 6.7.1(eslint@8.57.0)
|
||||
eslint-plugin-react: 7.33.2(eslint@8.57.0)
|
||||
eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0)
|
||||
typescript: 5.3.3
|
||||
typescript: 5.4.2
|
||||
transitivePeerDependencies:
|
||||
- eslint-import-resolver-webpack
|
||||
- supports-color
|
||||
@ -2030,7 +2030,7 @@ packages:
|
||||
enhanced-resolve: 5.15.0
|
||||
eslint: 8.57.0
|
||||
eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
|
||||
eslint-plugin-import: 2.28.1(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)
|
||||
eslint-plugin-import: 2.28.1(@typescript-eslint/parser@7.2.0)(eslint@8.57.0)
|
||||
fast-glob: 3.3.2
|
||||
get-tsconfig: 4.7.2
|
||||
is-core-module: 2.13.0
|
||||
@ -2088,7 +2088,7 @@ packages:
|
||||
eslint-import-resolver-webpack:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.2)
|
||||
debug: 3.2.7
|
||||
eslint: 8.57.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
@ -2097,7 +2097,7 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/eslint-module-utils@2.8.0(@typescript-eslint/parser@7.1.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0):
|
||||
/eslint-module-utils@2.8.0(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0):
|
||||
resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
|
||||
engines: {node: '>=4'}
|
||||
peerDependencies:
|
||||
@ -2118,7 +2118,7 @@ packages:
|
||||
eslint-import-resolver-webpack:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.4.2)
|
||||
debug: 3.2.7
|
||||
eslint: 8.57.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
@ -2126,7 +2126,7 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/eslint-plugin-import@2.28.1(@typescript-eslint/parser@7.1.0)(eslint@8.57.0):
|
||||
/eslint-plugin-import@2.28.1(@typescript-eslint/parser@7.2.0)(eslint@8.57.0):
|
||||
resolution: {integrity: sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==}
|
||||
engines: {node: '>=4'}
|
||||
peerDependencies:
|
||||
@ -2136,7 +2136,7 @@ packages:
|
||||
'@typescript-eslint/parser':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.4.2)
|
||||
array-includes: 3.1.7
|
||||
array.prototype.findlastindex: 1.2.3
|
||||
array.prototype.flat: 1.3.2
|
||||
@ -2145,7 +2145,7 @@ packages:
|
||||
doctrine: 2.1.0
|
||||
eslint: 8.57.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.1.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0)
|
||||
eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0)
|
||||
has: 1.0.4
|
||||
is-core-module: 2.13.0
|
||||
is-glob: 4.0.3
|
||||
@ -4528,8 +4528,8 @@ packages:
|
||||
'@types/nlcst': 1.0.4
|
||||
dev: false
|
||||
|
||||
/nodemailer@6.9.10:
|
||||
resolution: {integrity: sha512-qtoKfGFhvIFW5kLfrkw2R6Nm6Ur4LNUMykyqu6n9BRKJuyQrqEGwdXXUAbwWEKt33dlWUGXb7rzmJP/p4+O+CA==}
|
||||
/nodemailer@6.9.12:
|
||||
resolution: {integrity: sha512-pnLo7g37Br3jXbF0bl5DekBJihm2q+3bB3l2o/B060sWmb5l+VqeScAQCBqaQ+5ezRZFzW5SciZNGdRDEbq89w==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
dev: false
|
||||
|
||||
@ -4835,13 +4835,13 @@ packages:
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/prisma@5.10.2:
|
||||
resolution: {integrity: sha512-hqb/JMz9/kymRE25pMWCxkdyhbnIWrq+h7S6WysJpdnCvhstbJSNP/S6mScEcqiB8Qv2F+0R3yG+osRaWqZacQ==}
|
||||
/prisma@5.11.0:
|
||||
resolution: {integrity: sha512-KCLiug2cs0Je7kGkQBN9jDWoZ90ogE/kvZTUTgz2h94FEo8pczCkPH7fPNXkD1sGU7Yh65risGGD1HQ5DF3r3g==}
|
||||
engines: {node: '>=16.13'}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
'@prisma/engines': 5.10.2
|
||||
'@prisma/engines': 5.11.0
|
||||
|
||||
/proc-log@3.0.0:
|
||||
resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==}
|
||||
@ -4886,8 +4886,8 @@ packages:
|
||||
scheduler: 0.23.0
|
||||
dev: false
|
||||
|
||||
/react-error-boundary@4.0.12(react@18.2.0):
|
||||
resolution: {integrity: sha512-kJdxdEYlb7CPC1A0SeUY38cHpjuu6UkvzKiAmqmOFL21VRfMhOcWxTCBgLVCO0VEMh9JhFNcVaXlV4/BTpiwOA==}
|
||||
/react-error-boundary@4.0.13(react@18.2.0):
|
||||
resolution: {integrity: sha512-b6PwbdSv8XeOSYvjt8LpgpKrZ0yGdtZokYwkwV2wlcZbxgopHX/hgPl5VgpnoVOWd868n1hktM8Qm4b+02MiLQ==}
|
||||
peerDependencies:
|
||||
react: '>=16.13.1'
|
||||
dependencies:
|
||||
@ -4923,13 +4923,13 @@ packages:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/react-innertext@1.1.5(@types/react@18.2.60)(react@18.2.0):
|
||||
/react-innertext@1.1.5(@types/react@18.2.65)(react@18.2.0):
|
||||
resolution: {integrity: sha512-PWAqdqhxhHIv80dT9znP2KvS+hfkbRovFp4zFYHFFlOoQLRiawIic81gKb3U1wEyJZgMwgs3JoLtwryASRWP3Q==}
|
||||
peerDependencies:
|
||||
'@types/react': '>=0.0.0 <=99'
|
||||
react: '>=0.0.0 <=99'
|
||||
dependencies:
|
||||
'@types/react': 18.2.60
|
||||
'@types/react': 18.2.65
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
@ -4953,8 +4953,8 @@ packages:
|
||||
resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
|
||||
dev: false
|
||||
|
||||
/react-player@2.14.1(react@18.2.0):
|
||||
resolution: {integrity: sha512-jILj7F9o+6NHzrJ1GqZIxfJgskvGmKeJ05FNhPvgiCpvMZFmFneKEkukywHcULDO2lqITm+zcEkLSq42mX0FbA==}
|
||||
/react-player@2.15.1(react@18.2.0):
|
||||
resolution: {integrity: sha512-ni1XFuYZuhIKKdeFII+KRLmIPcvCYlyXvtSMhNOgssdfnSovmakBtBTW2bxowPvmpKy5BTR4jC4CF79ucgHT+g==}
|
||||
peerDependencies:
|
||||
react: '>=16.6.0'
|
||||
dependencies:
|
||||
@ -4966,7 +4966,7 @@ packages:
|
||||
react-fast-compare: 3.2.2
|
||||
dev: false
|
||||
|
||||
/react-textarea-autosize@8.5.3(@types/react@18.2.60)(react@18.2.0):
|
||||
/react-textarea-autosize@8.5.3(@types/react@18.2.65)(react@18.2.0):
|
||||
resolution: {integrity: sha512-XT1024o2pqCuZSuBt9FwHlaDeNtVrtCXu0Rnz88t1jUGheCLa3PhjE1GH8Ctm2axEtvdCl5SUHYschyQ0L5QHQ==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
@ -4975,7 +4975,7 @@ packages:
|
||||
'@babel/runtime': 7.23.1
|
||||
react: 18.2.0
|
||||
use-composed-ref: 1.3.0(react@18.2.0)
|
||||
use-latest: 1.2.1(@types/react@18.2.60)(react@18.2.0)
|
||||
use-latest: 1.2.1(@types/react@18.2.65)(react@18.2.0)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
dev: false
|
||||
@ -5405,8 +5405,8 @@ packages:
|
||||
engines: {node: '>=14'}
|
||||
dev: true
|
||||
|
||||
/simple-git-hooks@2.9.0:
|
||||
resolution: {integrity: sha512-waSQ5paUQtyGC0ZxlHmcMmD9I1rRXauikBwX31bX58l5vTOhCEcBC5Bi+ZDkPXTjDnZAF8TbCqKBY+9+sVPScw==}
|
||||
/simple-git-hooks@2.10.0:
|
||||
resolution: {integrity: sha512-TtCytVYfV77pILCkzVxpOSgYKHQyaO7fBI/iwG5bLGb0dIo/v/K1Y1IZ5DN40RQu6WNNJiN0gkuRvSYjxOhFog==}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
@ -5725,13 +5725,13 @@ packages:
|
||||
/trough@2.1.0:
|
||||
resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==}
|
||||
|
||||
/ts-api-utils@1.0.3(typescript@5.3.3):
|
||||
/ts-api-utils@1.0.3(typescript@5.4.2):
|
||||
resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==}
|
||||
engines: {node: '>=16.13.0'}
|
||||
peerDependencies:
|
||||
typescript: '>=4.2.0'
|
||||
dependencies:
|
||||
typescript: 5.3.3
|
||||
typescript: 5.4.2
|
||||
dev: true
|
||||
|
||||
/tsconfig-paths@3.14.2:
|
||||
@ -5804,8 +5804,8 @@ packages:
|
||||
resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==}
|
||||
dev: true
|
||||
|
||||
/typescript@5.3.3:
|
||||
resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==}
|
||||
/typescript@5.4.2:
|
||||
resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
@ -5832,7 +5832,7 @@ packages:
|
||||
'@types/concat-stream': 2.0.0
|
||||
'@types/debug': 4.1.12
|
||||
'@types/is-empty': 1.2.1
|
||||
'@types/node': 20.11.22
|
||||
'@types/node': 20.11.26
|
||||
'@types/unist': 3.0.2
|
||||
'@ungap/structured-clone': 1.2.0
|
||||
concat-stream: 2.0.0
|
||||
@ -6020,7 +6020,7 @@ packages:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/use-isomorphic-layout-effect@1.1.2(@types/react@18.2.60)(react@18.2.0):
|
||||
/use-isomorphic-layout-effect@1.1.2(@types/react@18.2.65)(react@18.2.0):
|
||||
resolution: {integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
@ -6029,11 +6029,11 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 18.2.60
|
||||
'@types/react': 18.2.65
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/use-latest@1.2.1(@types/react@18.2.60)(react@18.2.0):
|
||||
/use-latest@1.2.1(@types/react@18.2.65)(react@18.2.0):
|
||||
resolution: {integrity: sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
@ -6042,9 +6042,9 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 18.2.60
|
||||
'@types/react': 18.2.65
|
||||
react: 18.2.0
|
||||
use-isomorphic-layout-effect: 1.1.2(@types/react@18.2.60)(react@18.2.0)
|
||||
use-isomorphic-layout-effect: 1.1.2(@types/react@18.2.65)(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/use-sync-external-store@1.2.0(react@18.2.0):
|
||||
|
@ -34,6 +34,7 @@
|
||||
- Prisma
|
||||
- PlanetScale
|
||||
- Giscus
|
||||
- Resend
|
||||
- Fathom Analytics
|
||||
- ...and more: https://jarv.is/uses/
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user