diff --git a/README.md b/README.md index 74a7f5cd..cb12ef79 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ You can change these to your liking. - `API_URL`: defaults to localhost:3001, but allows you to host the front-end separately from the backend on a service like Vercel or Netlify - `WELCOME_CONTENT`: a markdown string (with \n newlines) that's rendered on the home page - `WELCOME_TITLE`: the file title for the post on the homepage. +- `SECRET_KEY`: a secret key used for validating API requests that is never exposed to the browser `server/.env`: @@ -38,6 +39,7 @@ You can change these to your liking. - `JWT_SECRET`: a secure token for JWT tokens. You can generate one [here](https://www.grc.com/passwords.htm). - `MEMORY_DB`: if `true`, a sqlite database will not be created and changes will only exist in memory. Mainly for the demo. - `REGISTRATION_PASSWORD`: if MEMORY_DB is not `true`, the user will be required to provide this password to sign-up, in addition to their username and account password. If it's not set, no password will be required. +- `SECRET_KEY`: the same secret key as the client ## Current status diff --git a/client/.env.local b/client/.env.local index 3bcbece7..a4e28f86 100644 --- a/client/.env.local +++ b/client/.env.local @@ -1,3 +1,4 @@ API_URL=http://localhost:3000 WELCOME_TITLE="Welcome to Drift" WELCOME_CONTENT="### Drift is a self-hostable clone of GitHub Gist. \nIt is a simple way to share code and text snippets with your friends, with support for the following:\n \n - Render GitHub Extended Markdown (including images)\n - User authentication\n - Private, public, and secret posts\n \n If you want to signup, you can join at [/signup](/signup) as long as you have a passcode provided by the administrator (which you don\'t need for this demo).\n **This demo is on a memory-only database, so accounts and pastes can be deleted at any time.**\n You can find the source code on [GitHub](https://github.com/MaxLeiter/drift).\n \n Drift was inspired by [this tweet](https://twitter.com/emilyst/status/1499858264346935297):\n > What is the absolute closest thing to GitHub Gist that can be self-hosted?\n In terms of design and functionality. Hosts images and markdown, rendered. Creates links that can be private or public. Uses/requires registration. I have looked at dozens of pastebin-like things." +SECRET_KEY=secret \ No newline at end of file diff --git a/client/components/document/formatting-icons/index.tsx b/client/components/document/formatting-icons/index.tsx index d5e15fe1..288e7daa 100644 --- a/client/components/document/formatting-icons/index.tsx +++ b/client/components/document/formatting-icons/index.tsx @@ -1,5 +1,8 @@ import { ButtonGroup, Button } from "@geist-ui/core" -import { Bold, Italic, Link, Image as ImageIcon } from '@geist-ui/icons' +import Bold from '@geist-ui/icons/bold' +import Italic from '@geist-ui/icons/italic' +import Link from '@geist-ui/icons/link' +import ImageIcon from '@geist-ui/icons/image' import { RefObject, useCallback, useMemo } from "react" import styles from '../document.module.css' @@ -20,7 +23,7 @@ const FormattingIcons = ({ textareaRef, setText }: { textareaRef?: RefObject { + const handleBoldClick = useCallback(() => { if (textareaRef?.current && setText) { const selectionStart = textareaRef.current.selectionStart const selectionEnd = textareaRef.current.selectionEnd @@ -37,7 +40,7 @@ const FormattingIcons = ({ textareaRef, setText }: { textareaRef?: RefObject { + const handleItalicClick = useCallback(() => { if (textareaRef?.current && setText) { const selectionStart = textareaRef.current.selectionStart const selectionEnd = textareaRef.current.selectionEnd @@ -52,7 +55,7 @@ const FormattingIcons = ({ textareaRef, setText }: { textareaRef?: RefObject { + const handleLinkClick = useCallback(() => { if (textareaRef?.current && setText) { const selectionStart = textareaRef.current.selectionStart const selectionEnd = textareaRef.current.selectionEnd @@ -73,7 +76,7 @@ const FormattingIcons = ({ textareaRef, setText }: { textareaRef?: RefObject { + const handleImageClick = useCallback(() => { if (textareaRef?.current && setText) { const selectionStart = textareaRef.current.selectionStart const selectionEnd = textareaRef.current.selectionEnd @@ -134,4 +137,4 @@ const FormattingIcons = ({ textareaRef, setText }: { textareaRef?: RefObject { const switchThemes = (type: string | string[]) => { changeTheme() - if (typeof window === 'undefined' || !window.localStorage) return - window.localStorage.setItem('drift-theme', Array.isArray(type) ? type[0] : type) + Cookies.set('drift-theme', Array.isArray(type) ? type[0] : type) } diff --git a/client/components/header/index.tsx b/client/components/header/index.tsx index d5905f22..c90291dc 100644 --- a/client/components/header/index.tsx +++ b/client/components/header/index.tsx @@ -1,11 +1,21 @@ import { Page, ButtonGroup, Button, useBodyScroll, useMediaQuery, Tabs, Spacer } from "@geist-ui/core"; -import { Github as GitHubIcon, UserPlus as SignUpIcon, User as SignInIcon, Home as HomeIcon, Menu as MenuIcon, Tool as SettingsIcon, UserX as SignoutIcon, PlusCircle as NewIcon, List as YourIcon, Moon, Sun } from "@geist-ui/icons"; import { DriftProps } from "../../pages/_app"; -import { useEffect, useMemo, useState } from "react"; +import { useEffect, useState } from "react"; import styles from './header.module.css'; import { useRouter } from "next/router"; import useSignedIn from "../../lib/hooks/use-signed-in"; +import HomeIcon from '@geist-ui/icons/home'; +import MenuIcon from '@geist-ui/icons/menu'; +import GitHubIcon from '@geist-ui/icons/github'; +import SignOutIcon from '@geist-ui/icons/userX'; +import SignInIcon from '@geist-ui/icons/user'; +import SignUpIcon from '@geist-ui/icons/userPlus'; +import NewIcon from '@geist-ui/icons/plusCircle'; +import YourIcon from '@geist-ui/icons/list' +import MoonIcon from '@geist-ui/icons/moon'; +import SunIcon from '@geist-ui/icons/sun'; + type Tab = { name: string icon: JSX.Element @@ -61,7 +71,7 @@ const Header = ({ changeTheme, theme }: DriftProps) => { { name: "Sign out", href: "/signout", - icon: , + icon: , condition: isSignedIn, value: "signout" }, @@ -94,7 +104,7 @@ const Header = ({ changeTheme, theme }: DriftProps) => { setSelectedTab(''); } }, - icon: theme === 'light' ? : , + icon: theme === 'light' ? : , condition: true, value: "theme", } diff --git a/client/components/my-posts/index.tsx b/client/components/my-posts/index.tsx index 15ea5892..80fbdba3 100644 --- a/client/components/my-posts/index.tsx +++ b/client/components/my-posts/index.tsx @@ -1,17 +1,7 @@ -import useSWR from "swr" import PostList from "../post-list" -import Cookies from "js-cookie" -const fetcher = (url: string) => fetch(url, { - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${Cookies.get("drift-token")}` - }, -}).then(r => r.json()) - -const MyPosts = () => { - const { data, error } = useSWR('/server-api/users/mine', fetcher) - return +const MyPosts = ({ posts, error }: { posts: any, error: any }) => { + return } export default MyPosts diff --git a/client/components/new-post/drag-and-drop/index.tsx b/client/components/new-post/drag-and-drop/index.tsx index dfae57ce..25de2bd7 100644 --- a/client/components/new-post/drag-and-drop/index.tsx +++ b/client/components/new-post/drag-and-drop/index.tsx @@ -1,10 +1,9 @@ -import { Button, Text, useTheme, useToasts } from '@geist-ui/core' -import { memo, useCallback, useEffect } from 'react' +import { Text, useTheme, useToasts } from '@geist-ui/core' +import { memo } from 'react' import { useDropzone } from 'react-dropzone' import styles from './drag-and-drop.module.css' -import { Document } from '../' +import type { Document } from '@lib/types' import generateUUID from '@lib/generate-uuid' -import { XCircle } from '@geist-ui/icons' const allowedFileTypes = [ 'application/json', 'application/x-javascript', @@ -99,7 +98,7 @@ function FileDropzone({ setDocs }: { setDocs: ((docs: Document[]) => void) }) { const { setToast } = useToasts() const onDrop = async (acceptedFiles: File[]) => { const newDocs = await Promise.all(acceptedFiles.map((file) => { - return new Promise((resolve, reject) => { + return new Promise((resolve) => { const reader = new FileReader() reader.onabort = () => setToast({ text: 'File reading was aborted', type: 'error' }) diff --git a/client/components/new-post/index.tsx b/client/components/new-post/index.tsx index 65b9f5a1..a962bb8e 100644 --- a/client/components/new-post/index.tsx +++ b/client/components/new-post/index.tsx @@ -2,28 +2,55 @@ import { Button, ButtonDropdown, useToasts } from '@geist-ui/core' import { useRouter } from 'next/router'; import { useCallback, useState } from 'react' import generateUUID from '@lib/generate-uuid'; -import Document from '../document'; +import DocumentComponent from '../document'; import FileDropzone from './drag-and-drop'; import styles from './post.module.css' import Title from './title'; import Cookies from 'js-cookie' - -export type Document = { - title: string - content: string - id: string -} +import type { PostVisibility, Document as DocumentType } from '@lib/types'; +import PasswordModal from './password'; +import getPostPath from '@lib/get-post-path'; const Post = () => { const { setToast } = useToasts() - const router = useRouter(); const [title, setTitle] = useState() - const [docs, setDocs] = useState([{ + const [docs, setDocs] = useState([{ title: '', content: '', id: generateUUID() }]) + const [passwordModalVisible, setPasswordModalVisible] = useState(false) + const sendRequest = useCallback(async (url: string, data: { visibility?: PostVisibility, title?: string, files?: DocumentType[], password?: string, userId: string }) => { + const res = await fetch(url, { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${Cookies.get('drift-token')}` + }, + body: JSON.stringify({ + title, + files: docs, + ...data, + }) + }) + + if (res.ok) { + const json = await res.json() + router.push(getPostPath(json.visibility, json.id)) + } else { + const json = await res.json() + setToast({ + text: json.message, + type: 'error' + }) + } + + }, [docs, router, setToast, title]) + + const closePasswordModel = () => { + setPasswordModalVisible(false) + } const [isSubmitting, setSubmitting] = useState(false) @@ -31,29 +58,25 @@ const Post = () => { setDocs(docs.filter((doc) => doc.id !== id)) } - const onSubmit = async (visibility: string) => { + const onSubmit = async (visibility: PostVisibility, password?: string) => { setSubmitting(true) - const response = await fetch('/server-api/posts/create', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${Cookies.get("drift-token")}` - }, - body: JSON.stringify({ - title, - files: docs, - visibility, - userId: Cookies.get("drift-userid"), - }) - }) - const json = await response.json() - setSubmitting(false) - if (json.id) - router.push(`/post/${json.id}`) - else { - setToast({ text: json.error.message, type: "error" }) + if (visibility === 'protected' && !password) { + setPasswordModalVisible(true) + return } + + await sendRequest('/server-api/posts/create', { + title, + files: docs, + visibility, + password, + userId: Cookies.get('drift-userid') || '' + }) + } + + const onClosePasswordModal = () => { + setPasswordModalVisible(false) } const updateTitle = useCallback((title: string, id: string) => { @@ -64,9 +87,9 @@ const Post = () => { setDocs(docs.map((doc) => doc.id === id ? { ...doc, content } : doc)) }, [docs]) - const uploadDocs = useCallback((files: Document[]) => { + const uploadDocs = useCallback((files: DocumentType[]) => { // if no title is set and the only document is empty, - const isFirstDocEmpty = docs.length === 1 && docs[0].title === '' && docs[0].content === '' + const isFirstDocEmpty = docs.length <= 1 && docs[0].title === '' && docs[0].content === '' const shouldSetTitle = !title && isFirstDocEmpty if (shouldSetTitle) { if (files.length === 1) { @@ -87,7 +110,7 @@ const Post = () => { { docs.map(({ content, id, title }) => { return ( - remove(id)} key={id} editable={true} @@ -120,10 +143,12 @@ const Post = () => { onSubmit('private')}>Create Private onSubmit('public')} >Create Public onSubmit('unlisted')} >Create Unlisted + onSubmit('protected')} >Create with Password + onSubmit('protected', password)} /> - + ) } -export default Post \ No newline at end of file +export default Post diff --git a/client/components/new-post/password/index.tsx b/client/components/new-post/password/index.tsx new file mode 100644 index 00000000..2305e945 --- /dev/null +++ b/client/components/new-post/password/index.tsx @@ -0,0 +1,50 @@ +import { Input, Modal, Note, Spacer } from "@geist-ui/core" +import { useState } from "react" + +type Props = { + isOpen: boolean + onClose: () => void + onSubmit: (password: string) => void +} + +const PasswordModal = ({ isOpen, onClose, onSubmit: onSubmitAfterVerify }: Props) => { + const [password, setPassword] = useState() + const [confirmPassword, setConfirmPassword] = useState() + const [error, setError] = useState() + + const onSubmit = () => { + if (!password || !confirmPassword) { + setError('Please enter a password') + return + } + + if (password !== confirmPassword) { + setError("Passwords do not match") + return + } + + onSubmitAfterVerify(password) + } + + return (<> + { + Enter a password + + {!error && + This doesn't protect your post from the server administrator. + } + {error && + {error} + } + + setPassword(e.target.value)} /> + setConfirmPassword(e.target.value)} /> + + Cancel + Submit + } + ) +} + + +export default PasswordModal \ No newline at end of file diff --git a/client/components/new-post/title/index.tsx b/client/components/new-post/title/index.tsx index d9b2302a..3865c858 100644 --- a/client/components/new-post/title/index.tsx +++ b/client/components/new-post/title/index.tsx @@ -1,4 +1,4 @@ -import { ChangeEvent, memo } from 'react' +import { memo } from 'react' import { Text, Input } from '@geist-ui/core' import ShiftBy from '@components/shift-by' import styles from '../post.module.css' diff --git a/client/components/post-list/list-item.tsx b/client/components/post-list/list-item.tsx index 30c37ecd..c034117f 100644 --- a/client/components/post-list/list-item.tsx +++ b/client/components/post-list/list-item.tsx @@ -4,6 +4,7 @@ import { useEffect, useMemo, useState } from "react" import timeAgo from "@lib/time-ago" import ShiftBy from "../shift-by" import VisibilityBadge from "../visibility-badge" +import getPostPath from "@lib/get-post-path" const FilenameInput = ({ title }: { title: string }) => { - + {post.title} diff --git a/client/components/preview/react-markdown-preview.tsx b/client/components/preview/react-markdown-preview.tsx index 92d9963d..5507aae2 100644 --- a/client/components/preview/react-markdown-preview.tsx +++ b/client/components/preview/react-markdown-preview.tsx @@ -1,14 +1,15 @@ import ReactMarkdown from "react-markdown" import remarkGfm from "remark-gfm" -import { PrismAsyncLight as SyntaxHighlighter } from 'react-syntax-highlighter'; +import SyntaxHighlighter from 'react-syntax-highlighter/dist/cjs/prism-async-light'; import rehypeSlug from 'rehype-slug' import rehypeAutolinkHeadings from 'rehype-autolink-headings' // @ts-ignore because of no types in remark-a11y-emoji -import a11yEmoji from '@fec/remark-a11y-emoji'; +// import a11yEmoji from '@fec/remark-a11y-emoji'; import styles from './preview.module.css' -import { vscDarkPlus as dark, vs as light } from 'react-syntax-highlighter/dist/cjs/styles/prism' +import dark from 'react-syntax-highlighter/dist/cjs/styles/prism/vsc-dark-plus' +import light from 'react-syntax-highlighter/dist/cjs/styles/prism/vs' import useSharedState from "@lib/hooks/use-shared-state"; type Props = { @@ -20,7 +21,7 @@ const ReactMarkdownPreview = ({ content, height }: Props) => { const [themeType] = useSharedState('theme') return (
{ diff --git a/client/lib/get-post-path.ts b/client/lib/get-post-path.ts new file mode 100644 index 00000000..47745319 --- /dev/null +++ b/client/lib/get-post-path.ts @@ -0,0 +1,13 @@ +import type { PostVisibility } from "./types" + +export default function getPostPath(visibility: PostVisibility, id: string) { + switch (visibility) { + case "private": + return `/post/private/${id}` + case "protected": + return `/post/protected/${id}` + case "unlisted": + case "public": + return `/post/${id}` + } +} diff --git a/client/lib/types.d.ts b/client/lib/types.d.ts new file mode 100644 index 00000000..c10b748a --- /dev/null +++ b/client/lib/types.d.ts @@ -0,0 +1,12 @@ +export type PostVisibility = "unlisted" | "private" | "public" | "protected" + +export type ThemeProps = { + theme: "light" | "dark" | string, + changeTheme: () => void +} + +export type Document = { + title: string + content: string + id: string +} diff --git a/client/next.config.js b/client/next.config.js index 16eb5923..d802e769 100644 --- a/client/next.config.js +++ b/client/next.config.js @@ -1,6 +1,10 @@ const dotenv = require("dotenv"); dotenv.config(); +const withBundleAnalyzer = require("@next/bundle-analyzer")({ + enabled: process.env.ANALYZE === "true", +}); + /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, @@ -21,4 +25,4 @@ const nextConfig = { }, }; -module.exports = nextConfig; +module.exports = withBundleAnalyzer(nextConfig); diff --git a/client/package.json b/client/package.json index cf6ce614..3e73c530 100644 --- a/client/package.json +++ b/client/package.json @@ -6,10 +6,10 @@ "dev": "next dev --port 3001", "build": "next build", "start": "next start", - "lint": "next lint" + "lint": "next lint", + "analyze": "ANALYZE=true next build" }, "dependencies": { - "@fec/remark-a11y-emoji": "^3.1.0", "@geist-ui/core": "^2.3.5", "@geist-ui/icons": "^1.0.1", "@types/cookie": "^0.4.1", @@ -19,7 +19,8 @@ "cookie": "^0.4.2", "dotenv": "^16.0.0", "js-cookie": "^3.0.1", - "next": "12.1.0", + "next": "^12.1.1-canary.15", + "prism-react-renderer": "^1.3.1", "prismjs": "^1.27.0", "react": "17.0.2", "react-debounce-render": "^8.0.2", @@ -31,18 +32,21 @@ "react-syntax-highlighter-virtualized-renderer": "^1.1.0", "rehype-autolink-headings": "^6.1.1", "rehype-katex": "^6.0.2", + "rehype-remark": "^9.1.2", "rehype-slug": "^5.0.1", - "rehype-stringify": "^9.0.3", "remark-gfm": "^3.0.1", "remark-math": "^5.1.1", "swr": "^1.2.2" }, "devDependencies": { + "@next/bundle-analyzer": "^12.1.0", "@types/node": "17.0.21", "@types/react": "17.0.39", + "@types/react-dom": "^17.0.14", "@types/react-syntax-highlighter": "^13.5.2", "eslint": "8.10.0", "eslint-config-next": "12.1.0", - "typescript": "4.6.2" + "typescript": "4.6.2", + "typescript-plugin-css-modules": "^3.4.0" } } diff --git a/client/pages/_app.tsx b/client/pages/_app.tsx index d3bf55d3..809a8834 100644 --- a/client/pages/_app.tsx +++ b/client/pages/_app.tsx @@ -7,17 +7,8 @@ import useSharedState from '@lib/hooks/use-shared-state'; import 'react-loading-skeleton/dist/skeleton.css' import { SkeletonTheme } from 'react-loading-skeleton'; import Head from 'next/head'; - -export type ThemeProps = { - theme: "light" | "dark" | string, - changeTheme: () => void -} - -export type PostProps = { - renderedPost: any | null, // Still don't have an official data type for posts - theme: "light" | "dark" | string, - changeTheme: () => void -} +import { ThemeProps } from '@lib/types'; +import Cookies from 'js-cookie'; type AppProps

= { pageProps: P; @@ -26,11 +17,10 @@ type AppProps

= { export type DriftProps = ThemeProps function MyApp({ Component, pageProps }: AppProps) { - const [themeType, setThemeType] = useSharedState('theme', 'light') - const theme = useTheme(); + const [themeType, setThemeType] = useSharedState('theme', Cookies.get('drift-theme') || 'light') + useEffect(() => { - if (typeof window === 'undefined' || !window.localStorage) return - const storedTheme = window.localStorage.getItem('drift-theme') + const storedTheme = Cookies.get('drift-theme') if (storedTheme) setThemeType(storedTheme) // TODO: useReducer? }, [setThemeType, themeType]) diff --git a/client/pages/_middleware.tsx b/client/pages/_middleware.tsx index e31452e4..a6c34478 100644 --- a/client/pages/_middleware.tsx +++ b/client/pages/_middleware.tsx @@ -2,7 +2,7 @@ import { NextFetchEvent, NextRequest, NextResponse } from 'next/server' const PUBLIC_FILE = /.(.*)$/ -export function middleware(req: NextRequest, ev: NextFetchEvent) { +export function middleware(req: NextRequest) { const pathname = req.nextUrl.pathname const signedIn = req.cookies['drift-token'] const getURL = (pageName: string) => new URL(`/${pageName}`, req.url).href diff --git a/client/pages/api/raw/[id].ts b/client/pages/api/raw/[id].ts index 62ef2745..4cfe4e52 100644 --- a/client/pages/api/raw/[id].ts +++ b/client/pages/api/raw/[id].ts @@ -2,13 +2,22 @@ import { NextApiRequest, NextApiResponse } from "next" const getRawFile = async (req: NextApiRequest, res: NextApiResponse) => { const { id, download } = req.query - const file = await fetch(`${process.env.API_URL}/files/raw/${id}`) + const file = await fetch(`${process.env.API_URL}/files/raw/${id}`, { + headers: { + 'Accept': 'text/plain', + 'x-secret-key': process.env.SECRET_KEY || '', + 'Authorization': `Bearer ${req.cookies['drift-token']}`, + } + }) + + res.setHeader("Content-Type", "text/plain") + res.setHeader('Cache-Control', 's-maxage=86400'); + if (file.ok) { const data = await file.json() const { title, content } = data // serve the file raw as plain text - res.setHeader("Content-Type", "text/plain") - res.setHeader('Cache-Control', 's-maxage=86400'); + if (download) { res.setHeader("Content-Disposition", `attachment; filename="${title}"`) } else { diff --git a/client/pages/index.tsx b/client/pages/index.tsx index 771d175b..c8303d83 100644 --- a/client/pages/index.tsx +++ b/client/pages/index.tsx @@ -2,11 +2,11 @@ import styles from '@styles/Home.module.css' import { Page, Spacer, Text } from '@geist-ui/core' import Header from '@components/header' -import { ThemeProps } from './_app' import Document from '@components/document' import Image from 'next/image' import ShiftBy from '@components/shift-by' import PageSeo from '@components/page-seo' +import { ThemeProps } from '@lib/types' export function getStaticProps() { const introDoc = process.env.WELCOME_CONTENT diff --git a/client/pages/mine.tsx b/client/pages/mine.tsx index b273d548..429c9dc6 100644 --- a/client/pages/mine.tsx +++ b/client/pages/mine.tsx @@ -3,18 +3,58 @@ import { Page } from '@geist-ui/core' import Header from '@components/header' import MyPosts from '@components/my-posts' +import cookie from "cookie"; +import { GetServerSideProps } from 'next'; +import { ThemeProps } from '@lib/types'; -const Home = ({ theme, changeTheme }: { theme: "light" | "dark", changeTheme: () => void }) => { +const Home = ({ posts, error, theme, changeTheme }: ThemeProps & { posts: any; error: any; }) => { return (

- + ) } +// get server side props +export const getServerSideProps: GetServerSideProps = async ({ req }) => { + const driftToken = cookie.parse(req.headers.cookie || '')[`drift-token`] + if (!driftToken) { + return { + redirect: { + destination: '/', + permanent: false, + } + } + } + + const posts = await fetch(process.env.API_URL + `/posts/mine`, { + method: "GET", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${driftToken}`, + "x-secret-key": process.env.SECRET_KEY || '' + } + }) + + if (!posts.ok || posts.status !== 200) { + return { + redirect: { + destination: '/', + permanent: false, + } + } + } + + return { + props: { + posts: await posts.json(), + error: posts.status !== 200, + } + } +} export default Home diff --git a/client/pages/new.tsx b/client/pages/new.tsx index b8966fc6..7a6f5948 100644 --- a/client/pages/new.tsx +++ b/client/pages/new.tsx @@ -3,12 +3,10 @@ import NewPost from '@components/new-post' import { Page } from '@geist-ui/core' import useSignedIn from '@lib/hooks/use-signed-in' import Header from '@components/header' -import { ThemeProps } from './_app' -import { useRouter } from 'next/router' import PageSeo from '@components/page-seo' +import { ThemeProps } from '@lib/types' const New = ({ theme, changeTheme }: ThemeProps) => { - const router = useRouter() const isSignedIn = useSignedIn() return ( diff --git a/client/pages/post/[id].tsx b/client/pages/post/[id].tsx index cddf7947..20c91bc8 100644 --- a/client/pages/post/[id].tsx +++ b/client/pages/post/[id].tsx @@ -1,45 +1,32 @@ import { Button, Page, Text } from "@geist-ui/core"; -import Skeleton from 'react-loading-skeleton'; -import { useRouter } from "next/router"; -import { useEffect, useState } from "react"; -import Document from '../../components/document' -import Header from "../../components/header"; -import VisibilityBadge from "../../components/visibility-badge"; -import { PostProps } from "../_app"; +import Document from '@components/document' +import Header from "@components/header"; +import VisibilityBadge from "@components/visibility-badge"; import PageSeo from "components/page-seo"; import styles from './styles.module.css'; -import Cookies from "js-cookie"; -import cookie from "cookie"; -import { GetServerSideProps } from "next"; +import type { GetStaticPaths, GetStaticProps } from "next"; +import { PostVisibility, ThemeProps } from "@lib/types"; +type File = { + id: string + title: string + content: string +} -const Post = ({renderedPost, theme, changeTheme}: PostProps) => { - const [post, setPost] = useState(renderedPost); - const [isLoading, setIsLoading] = useState(true) - const [error, setError] = useState() - const router = useRouter(); +type Files = File[] - useEffect(() => { - async function fetchPost() { - setIsLoading(true); - - if (renderedPost) { - setPost(renderedPost) - setIsLoading(false) - - return; - } - - if (!Cookies.get('drift-token')) { - router.push('/signin'); - } else { - setError('Something went wrong fetching the post'); - } - } - fetchPost() - }, [router, router.query.id]) +export type PostProps = ThemeProps & { + post: { + id: string + title: string + description: string + visibility: PostVisibility + files: Files + } +} +const Post = ({ post, theme, changeTheme }: PostProps) => { const download = async () => { const clientZip = require("client-zip") @@ -59,80 +46,74 @@ const Post = ({renderedPost, theme, changeTheme}: PostProps) => { return ( - {!isLoading && ( - - )} +
{/* {!isLoading && } */} - - {error && {error}} - {!error && isLoading && <> - - } - {!isLoading && post && <> -
-
- {post.title} - -
- +
+
+ {post.title} +
- {post.files.map(({ id, content, title }: { id: any, content: string, title: string }) => ( - - ))} - } + +
+ {post.files.map(({ id, content, title }: { id: any, content: string, title: string }) => ( + + ))} ) } -export const getServerSideProps: GetServerSideProps = async (context) => { - - const headers = context.req.headers; - const host = headers.host; - const driftToken = cookie.parse(headers.cookie || '')[`drift-token`]; - - let post; - - if (context.query.id) { - post = await fetch('http://' + host + `/server-api/posts/${context.query.id}`, { - method: "GET", - headers: { - "Content-Type": "application/json", - "Authorization": `Bearer ${driftToken}` - } - }); - - try { - post = await post.json(); - } catch (e) { - console.log(e); - post = null; +export const getStaticPaths: GetStaticPaths = async () => { + const posts = await fetch(process.env.API_URL + `/posts/`, { + method: "GET", + headers: { + "Content-Type": "application/json", + "x-secret-key": process.env.SECRET_KEY || "", } - } + }) + + const json = await posts.json() + const filtered = json.filter((post: any) => post.visibility === "public" || post.visibility === "unlisted") + const paths = filtered.map((post: any) => ({ + params: { id: post.id } + })) + + return { paths, fallback: 'blocking' } +} + +export const getStaticProps: GetStaticProps = async ({ params }) => { + const post = await fetch(process.env.API_URL + `/posts/${params?.id}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + "x-secret-key": process.env.SECRET_KEY || "", + } + }) return { props: { - renderedPost: post - } + post: await post.json() + }, } } export default Post + diff --git a/client/pages/post/private/[id].tsx b/client/pages/post/private/[id].tsx new file mode 100644 index 00000000..c9b43583 --- /dev/null +++ b/client/pages/post/private/[id].tsx @@ -0,0 +1,129 @@ +import { Button, Page, Text } from "@geist-ui/core"; + +import Document from '@components/document' +import Header from "@components/header"; +import VisibilityBadge from "@components/visibility-badge"; +import PageSeo from "components/page-seo"; +import styles from '../styles.module.css'; +import cookie from "cookie"; +import type { GetServerSideProps } from "next"; +import { PostVisibility, ThemeProps } from "@lib/types"; + +type File = { + id: string + title: string + content: string +} + +type Files = File[] + +export type PostProps = ThemeProps & { + post: { + id: string + title: string + description: string + visibility: PostVisibility + files: Files + } +} + +const Post = ({ post, theme, changeTheme }: PostProps) => { + const download = async () => { + const clientZip = require("client-zip") + + const blob = await clientZip.downloadZip(post.files.map((file: any) => { + return { + name: file.title, + input: file.content, + lastModified: new Date(file.updatedAt) + } + })).blob() + const link = document.createElement("a") + link.href = URL.createObjectURL(blob) + link.download = `${post.title}.zip` + link.click() + link.remove() + } + + return ( + + + + +
+ + + {/* {!isLoading && } */} +
+
+ {post.title} + +
+ +
+ {post.files.map(({ id, content, title }: { id: any, content: string, title: string }) => ( + + ))} +
+ + ) +} + +export const getServerSideProps: GetServerSideProps = async (context) => { + const headers = context.req.headers + const host = headers.host + const driftToken = cookie.parse(headers.cookie || '')[`drift-token`] + + if (context.query.id) { + const post = await fetch('http://' + host + `/server-api/posts/${context.query.id}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${driftToken}`, + "x-secret-key": process.env.SECRET_KEY || "", + } + }) + + if (!post.ok || post.status !== 200) { + return { + redirect: { + destination: '/', + permanent: false, + }, + } + } + try { + const json = await post.json(); + + return { + props: { + post: json + } + } + } catch (e) { + console.log(e) + } + } + + return { + props: { + post: null + } + } +} + +export default Post + diff --git a/client/pages/signin.tsx b/client/pages/signin.tsx index defc7d5b..0b98aabc 100644 --- a/client/pages/signin.tsx +++ b/client/pages/signin.tsx @@ -2,7 +2,7 @@ import { Page } from "@geist-ui/core"; import PageSeo from "@components/page-seo"; import Auth from "@components/auth"; import Header from "@components/header"; -import { ThemeProps } from "./_app"; +import { ThemeProps } from "@lib/types"; const SignIn = ({ theme, changeTheme }: ThemeProps) => ( diff --git a/client/pages/signup.tsx b/client/pages/signup.tsx index 3628ef6d..9aa7b734 100644 --- a/client/pages/signup.tsx +++ b/client/pages/signup.tsx @@ -2,7 +2,7 @@ import { Page } from "@geist-ui/core"; import Auth from "@components/auth"; import Header from "@components/header"; import PageSeo from '@components/page-seo'; -import { ThemeProps } from "./_app"; +import { ThemeProps } from "@lib/types"; const SignUp = ({ theme, changeTheme }: ThemeProps) => ( diff --git a/client/tsconfig.json b/client/tsconfig.json index 759858c9..2088465b 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -1,15 +1,26 @@ { "compilerOptions": { - "target": "es5", + "plugins": [{ "name": "typescript-plugin-css-modules" }], + "target": "es2020", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "strict": true, "forceConsistentCasingInFileNames": true, + "noImplicitAny": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "strictBindCallApply": true, + "strictPropertyInitialization": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedLocals": false, + "noUnusedParameters": true, "noEmit": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "node", + "allowSyntheticDefaultImports": true, "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", diff --git a/client/yarn.lock b/client/yarn.lock index 2ba24293..7dbfe7ad 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -32,16 +32,6 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@fec/remark-a11y-emoji@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@fec/remark-a11y-emoji/-/remark-a11y-emoji-3.1.0.tgz#765ead0e26b6f06878f246c6e920a6edf0a5dc08" - integrity sha512-cYjCutvrValbQ2dykKhEE6OBTsEGpAJzeJnDtGKXhk2JYkMNSlKPnUk/kRFHH+PHmrAF+FlNIU28XKD+nYy7jQ== - dependencies: - emoji-regex "^9.2.0" - gemoji "^6.1.0" - mdast-util-find-and-replace "^1.0.0" - unist-util-visit "^2.0.3" - "@geist-ui/core@^2.3.5": version "2.3.5" resolved "https://registry.yarnpkg.com/@geist-ui/core/-/core-2.3.5.tgz#9b9f64f1c26e9fa68eb7e2bc4a2c1022ee353f66" @@ -68,10 +58,17 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== -"@next/env@12.1.0": +"@next/bundle-analyzer@^12.1.0": version "12.1.0" - resolved "https://registry.yarnpkg.com/@next/env/-/env-12.1.0.tgz#73713399399b34aa5a01771fb73272b55b22c314" - integrity sha512-nrIgY6t17FQ9xxwH3jj0a6EOiQ/WDHUos35Hghtr+SWN/ntHIQ7UpuvSi0vaLzZVHQWaDupKI+liO5vANcDeTQ== + resolved "https://registry.yarnpkg.com/@next/bundle-analyzer/-/bundle-analyzer-12.1.0.tgz#9f6d6cda2a26220c936805be407243e22790f4b7" + integrity sha512-pOtWRWaKQXff8A80Ex3E67EH8XuERHxBPn8cQgKzfhRKQwoTEareHe2nWJO1uXTQm6m7ZRhmhb4+uwp+UvmITQ== + dependencies: + webpack-bundle-analyzer "4.3.0" + +"@next/env@12.1.1-canary.15": + version "12.1.1-canary.15" + resolved "https://registry.yarnpkg.com/@next/env/-/env-12.1.1-canary.15.tgz#d1c210df31c8865042f2b81ffb37660b9cc70045" + integrity sha512-2r7r5r/+hSgCTeGTMErGwlxiawNX3RGCKrgWGyyIYKGcJ2xunxN3ScDKIAjGa77eOWGm4JccB4T6xXwmPUut5g== "@next/eslint-plugin-next@12.1.0": version "12.1.0" @@ -80,60 +77,65 @@ dependencies: glob "7.1.7" -"@next/swc-android-arm64@12.1.0": - version "12.1.0" - resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.1.0.tgz#865ba3a9afc204ff2bdeea49dd64d58705007a39" - integrity sha512-/280MLdZe0W03stA69iL+v6I+J1ascrQ6FrXBlXGCsGzrfMaGr7fskMa0T5AhQIVQD4nA/46QQWxG//DYuFBcA== +"@next/swc-android-arm-eabi@12.1.1-canary.15": + version "12.1.1-canary.15" + resolved "https://registry.yarnpkg.com/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.1.1-canary.15.tgz#4539e24cc64fe8f76ce48c7e37c4419f9f436566" + integrity sha512-I1ghAtx23GcVi7modLdXLZZgfngcLzgzx/mWVXhWa2Pl8NPippIDMNF10Kf75RnOgkrPAEbVJByXAAEY7OkG6g== -"@next/swc-darwin-arm64@12.1.0": - version "12.1.0" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.0.tgz#08e8b411b8accd095009ed12efbc2f1d4d547135" - integrity sha512-R8vcXE2/iONJ1Unf5Ptqjk6LRW3bggH+8drNkkzH4FLEQkHtELhvcmJwkXcuipyQCsIakldAXhRbZmm3YN1vXg== +"@next/swc-android-arm64@12.1.1-canary.15": + version "12.1.1-canary.15" + resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.1.1-canary.15.tgz#929ca296b7bfb7fdac77645d53199792d631048f" + integrity sha512-qa8M33AUfCW+P8NqGYd77+qhcM+QAP/KD7DBzCoIB08Djf/IQ3xBshM8dvCgWTYYz1ydnlHbMmJk+xiApoEfbQ== -"@next/swc-darwin-x64@12.1.0": - version "12.1.0" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.0.tgz#fcd684497a76e8feaca88db3c394480ff0b007cd" - integrity sha512-ieAz0/J0PhmbZBB8+EA/JGdhRHBogF8BWaeqR7hwveb6SYEIJaDNQy0I+ZN8gF8hLj63bEDxJAs/cEhdnTq+ug== +"@next/swc-darwin-arm64@12.1.1-canary.15": + version "12.1.1-canary.15" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.1-canary.15.tgz#99764be54f9f9ba9866de18bc23f0fcfc98ac217" + integrity sha512-9L8X49wug00GpM4iIakq1MmsXKvWykwYjQRt++brGA4/rCJlG6WUiM4WDBQr2QqLCTMrfbd5umQ3qbL0F23VkQ== -"@next/swc-linux-arm-gnueabihf@12.1.0": - version "12.1.0" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.0.tgz#9ec6380a27938a5799aaa6035c205b3c478468a7" - integrity sha512-njUd9hpl6o6A5d08dC0cKAgXKCzm5fFtgGe6i0eko8IAdtAPbtHxtpre3VeSxdZvuGFh+hb0REySQP9T1ttkog== +"@next/swc-darwin-x64@12.1.1-canary.15": + version "12.1.1-canary.15" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.1-canary.15.tgz#4bdda400c5e542ff3355078a175fa6f74a20e39d" + integrity sha512-SMldDPyrN1GVqLYcXEUs7rwxbRP7ra8OxmRre3MJcUq1TB+mVkasNCDCO6WX1pJ9vDxu5Z5WuiBlp8bioCCp1w== -"@next/swc-linux-arm64-gnu@12.1.0": - version "12.1.0" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.0.tgz#7f4196dff1049cea479607c75b81033ae2dbd093" - integrity sha512-OqangJLkRxVxMhDtcb7Qn1xjzFA3s50EIxY7mljbSCLybU+sByPaWAHY4px97ieOlr2y4S0xdPKkQ3BCAwyo6Q== +"@next/swc-linux-arm-gnueabihf@12.1.1-canary.15": + version "12.1.1-canary.15" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.1-canary.15.tgz#f066f295cefe4206093614e2db292ef435ff7734" + integrity sha512-f8YBO686RvqfjIc8gv9gRJFPOSLEdtuJ1Q8FassJ2Jy4GMZdCGJaVFbcavsnd1ksw/KVxC79GaVigSVRmmgArA== -"@next/swc-linux-arm64-musl@12.1.0": - version "12.1.0" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.0.tgz#b445f767569cdc2dddee785ca495e1a88c025566" - integrity sha512-hB8cLSt4GdmOpcwRe2UzI5UWn6HHO/vLkr5OTuNvCJ5xGDwpPXelVkYW/0+C3g5axbDW2Tym4S+MQCkkH9QfWA== +"@next/swc-linux-arm64-gnu@12.1.1-canary.15": + version "12.1.1-canary.15" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.1-canary.15.tgz#a176237eedbdf8895c254f207d7e39a64b29c6b2" + integrity sha512-2J8LWInvvm7iNlx/mmH+BqUwLQndHKaFxgoLPqpVnn3XaIsHgSl+d9jU0ECJrp9OtzVgFmFgJYIfRMq9dNRDFw== -"@next/swc-linux-x64-gnu@12.1.0": - version "12.1.0" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.0.tgz#67610e9be4fbc987de7535f1bcb17e45fe12f90e" - integrity sha512-OKO4R/digvrVuweSw/uBM4nSdyzsBV5EwkUeeG4KVpkIZEe64ZwRpnFB65bC6hGwxIBnTv5NMSnJ+0K/WmG78A== +"@next/swc-linux-arm64-musl@12.1.1-canary.15": + version "12.1.1-canary.15" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.1-canary.15.tgz#235e44bf445e3e2b9dd01e757396520e7f57addf" + integrity sha512-SGEuapk5eheIsCE9tdLL5hxomUSQvETT9KCss8/x/+44009iBXsuKFP6DdF+0GFJzv/rpO+6ijPfnwQnvzTxeQ== -"@next/swc-linux-x64-musl@12.1.0": - version "12.1.0" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.0.tgz#ea19a23db08a9f2e34ac30401f774cf7d1669d31" - integrity sha512-JohhgAHZvOD3rQY7tlp7NlmvtvYHBYgY0x5ZCecUT6eCCcl9lv6iV3nfu82ErkxNk1H893fqH0FUpznZ/H3pSw== +"@next/swc-linux-x64-gnu@12.1.1-canary.15": + version "12.1.1-canary.15" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.1-canary.15.tgz#a89ca271a575335b6ed385d718792409ae85783c" + integrity sha512-9cgczb1Mr1BNZBxH5a02ermKGLihpBlp1ZVeIYwSGv+WFGCBIirIbZfvWDXpLG2fdA1YbPk1122o2h8ItVLlJw== -"@next/swc-win32-arm64-msvc@12.1.0": - version "12.1.0" - resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.0.tgz#eadf054fc412085659b98e145435bbba200b5283" - integrity sha512-T/3gIE6QEfKIJ4dmJk75v9hhNiYZhQYAoYm4iVo1TgcsuaKLFa+zMPh4056AHiG6n9tn2UQ1CFE8EoybEsqsSw== +"@next/swc-linux-x64-musl@12.1.1-canary.15": + version "12.1.1-canary.15" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.1-canary.15.tgz#b8ee5f2cbefedd305da286a2d10633656b85092a" + integrity sha512-nCqi/WVjp0PwQLBE7QPe4wNm6Hontuwh5p8ZIOmiSIGkxvbHdPbXWomKQFCwm2387B1OLGzv9VFJ0cBcfEbjWA== -"@next/swc-win32-ia32-msvc@12.1.0": - version "12.1.0" - resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.0.tgz#68faeae10c89f698bf9d28759172b74c9c21bda1" - integrity sha512-iwnKgHJdqhIW19H9PRPM9j55V6RdcOo6rX+5imx832BCWzkDbyomWnlzBfr6ByUYfhohb8QuH4hSGEikpPqI0Q== +"@next/swc-win32-arm64-msvc@12.1.1-canary.15": + version "12.1.1-canary.15" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.1-canary.15.tgz#094dab65bba62d516077539e7fc8edf6dd57ebc2" + integrity sha512-HO7Pcgky002h7xyjFdwbondKUXbDdxDcPQqxH4hUYg3umZr9dW2fTwKh6BTFDODeb9PtST+KaW4erFJPzRPYJw== -"@next/swc-win32-x64-msvc@12.1.0": - version "12.1.0" - resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.1.0.tgz#d27e7e76c87a460a4da99c5bfdb1618dcd6cd064" - integrity sha512-aBvcbMwuanDH4EMrL2TthNJy+4nP59Bimn8egqv6GHMVj0a44cU6Au4PjOhLNqEh9l+IpRGBqMTzec94UdC5xg== +"@next/swc-win32-ia32-msvc@12.1.1-canary.15": + version "12.1.1-canary.15" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.1-canary.15.tgz#2015910672229c11b11e3f10941fcee7c3dd2e10" + integrity sha512-llK5rpggUbe2OseHRQ32q8EjQHk8remoKrqlbXTJrEz9Fa6BNx8uI/IAT6tr9oX6VgTBeIFu1kX20yXJFxsL3Q== + +"@next/swc-win32-x64-msvc@12.1.1-canary.15": + version "12.1.1-canary.15" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.1.1-canary.15.tgz#d1b08175419161cc0e4435333f5f7ca3b617708f" + integrity sha512-VcbXco9q82qHqBebHfPZqAgfs6OLek7EJJt28/OaSBnCJGzCl0hkWo3NkHEI4SQwYzTAgMufU3a9WjkEz3Oeew== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -156,6 +158,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@polka/url@^1.0.0-next.20": + version "1.0.0-next.21" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1" + integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g== + "@rushstack/eslint-patch@^1.0.8": version "1.1.0" resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz#7f698254aadf921e48dda8c0a6b304026b8a9323" @@ -173,6 +180,11 @@ dependencies: "@types/ms" "*" +"@types/extend@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/extend/-/extend-3.0.1.tgz#923dc2d707d944382433e01d6cc0c69030ab2c75" + integrity sha512-R1g/VyKFFI2HLC1QGAeTtCBWCo6n75l41OnsVYNbmKG+kempOESaodf6BeJyUM3Q0rKa/NQcTHbB2+66lNnxLw== + "@types/hast@^2.0.0": version "2.3.4" resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc" @@ -227,6 +239,13 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11" integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ== +"@types/react-dom@^17.0.14": + version "17.0.14" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.14.tgz#c8f917156b652ddf807711f5becbd2ab018dea9f" + integrity sha512-H03xwEP1oXmSfl3iobtmQ/2dHF5aBHr8aUMwyGZya6OW45G+xtdzmq6HkncefiBt5JU8DVyaWl/nWZbjZCnzAQ== + dependencies: + "@types/react" "*" + "@types/react-syntax-highlighter@^13.5.2": version "13.5.2" resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-13.5.2.tgz#357cc03581dc434c57c3b31f70e0eecdbf7b3ab0" @@ -302,7 +321,12 @@ acorn-jsx@^5.3.1: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.7.0: +acorn-walk@^8.0.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^8.0.4, acorn@^8.7.0: version "8.7.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== @@ -322,6 +346,13 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" @@ -329,6 +360,14 @@ ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + argparse@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" @@ -381,6 +420,11 @@ ast-types-flow@^0.0.7: resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + attr-accept@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.2.tgz#646613809660110749e92f2c10833b70968d929b" @@ -414,6 +458,16 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -422,7 +476,7 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^3.0.1: +braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -452,7 +506,16 @@ ccount@^2.0.0: resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== -chalk@^4.0.0: +chalk@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -460,21 +523,11 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -character-entities-html4@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz#1f1adb940c971a4b22ba39ddca6b618dc6e56b2b" - integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== - character-entities-legacy@^1.0.0: version "1.1.4" resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== -character-entities-legacy@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz#76bc83a90738901d7bc223a9e93759fdd560125b" - integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== - character-entities@^1.0.0: version "1.2.4" resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" @@ -490,6 +543,21 @@ character-reference-invalid@^1.0.0: resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== +"chokidar@>=3.0.0 <4.0.0": + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + client-zip@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/client-zip/-/client-zip-2.0.0.tgz#c93676c92ddb40c858da83517c27297a53874f8d" @@ -500,6 +568,13 @@ clsx@^1.0.4: resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -507,6 +582,11 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" @@ -527,6 +607,11 @@ comma-separated-tokens@^2.0.0: resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz#d4c25abb679b7751c880be623c1179780fe1dd98" integrity sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg== +commander@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + commander@^8.0.0: version "8.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" @@ -542,6 +627,13 @@ cookie@^0.4.2: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== +copy-anything@^2.0.1: + version "2.0.6" + resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-2.0.6.tgz#092454ea9584a7b7ad5573062b2a87f5900fc480" + integrity sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw== + dependencies: + is-what "^3.14.1" + core-js-pure@^3.20.2: version "3.21.1" resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.21.1.tgz#8c4d1e78839f5f46208de7230cebfb72bc3bdb51" @@ -561,6 +653,36 @@ cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" +css-parse@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-2.0.0.tgz#a468ee667c16d81ccf05c58c38d2a97c780dbfd4" + integrity sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q= + dependencies: + css "^2.0.0" + +css-selector-tokenizer@^0.7.0: + version "0.7.3" + resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz#735f26186e67c749aaf275783405cf0661fae8f1" + integrity sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg== + dependencies: + cssesc "^3.0.0" + fastparse "^1.1.2" + +css@^2.0.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" + integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw== + dependencies: + inherits "^2.0.3" + source-map "^0.6.1" + source-map-resolve "^0.5.2" + urix "^0.1.0" + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + csstype@^3.0.2: version "3.0.11" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.11.tgz#d66700c5eacfac1940deb4e3ee5642792d85cd33" @@ -578,7 +700,7 @@ debug@^2.6.9: dependencies: ms "2.0.0" -debug@^3.2.7: +debug@^3.2.6, debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -592,6 +714,13 @@ debug@^4.0.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: dependencies: ms "2.1.2" +debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + decode-named-character-reference@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.0.1.tgz#57b2bd9112659cacbc449d3577d7dadb8e1f3d1b" @@ -599,6 +728,11 @@ decode-named-character-reference@^1.0.0: dependencies: character-entities "^2.0.0" +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -650,16 +784,38 @@ dom-helpers@^5.1.3: "@babel/runtime" "^7.8.7" csstype "^3.0.2" +dotenv@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" + integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== + dotenv@^16.0.0: version "16.0.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.0.tgz#c619001253be89ebb638d027b609c75c26e47411" integrity sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q== -emoji-regex@^9.2.0, emoji-regex@^9.2.2: +duplexer@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== + +emoji-regex@^9.2.2: version "9.2.2" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +errno@^0.1.1: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + es-abstract@^1.19.0, es-abstract@^1.19.1: version "1.19.1" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" @@ -695,6 +851,11 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" @@ -939,6 +1100,11 @@ fast-levenshtein@^2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fastparse@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" + integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ== + fastq@^1.6.0: version "1.13.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" @@ -1004,6 +1170,11 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -1014,10 +1185,12 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= -gemoji@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/gemoji/-/gemoji-6.1.0.tgz#268fbb0c81d1a8c32a4bcc39bdfdd66080ba7ce9" - integrity sha512-MOlX3doQ1fsfzxQX8Y+u6bC5Ssc1pBUBIPVyrS69EzKt+5LIZAOm0G5XGVNhwXFgkBF3r+Yk88ONyrFHo8iNFA== +generic-names@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/generic-names/-/generic-names-1.0.3.tgz#2d786a121aee508876796939e8e3bff836c20917" + integrity sha1-LXhqEhruUIh2eWk56OO/+DbCCRc= + dependencies: + loader-utils "^0.2.16" get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: version "1.1.1" @@ -1041,7 +1214,7 @@ github-slugger@^1.1.1: resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.4.0.tgz#206eb96cdb22ee56fdc53a28d5a302338463444e" integrity sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ== -glob-parent@^5.1.2: +glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -1067,7 +1240,7 @@ glob@7.1.7: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.3, glob@^7.1.7: +glob@^7.1.3, glob@^7.1.6, glob@^7.1.7: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== @@ -1098,11 +1271,28 @@ globby@^11.0.4: merge2 "^1.4.1" slash "^3.0.0" +graceful-fs@^4.1.2: + version "4.2.9" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" + integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== + +gzip-size@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" + integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q== + dependencies: + duplexer "^0.1.2" + has-bigints@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" @@ -1127,6 +1317,13 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +hast-util-embedded@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hast-util-embedded/-/hast-util-embedded-2.0.0.tgz#877f4261044854743fc2621f728930ca61c8376f" + integrity sha512-vEr54rDu2CheBM4nLkWbW8Rycf8HhkA/KsrDnlyKnvBTyhyO+vAG6twHnfUbiRGo56YeUBNCI4HFfHg3Wu+tig== + dependencies: + hast-util-is-element "^2.0.0" + hast-util-from-parse5@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-7.1.0.tgz#c129dd3a24dd8a867ab8a029ca47e27aa54864b7" @@ -1173,21 +1370,25 @@ hast-util-parse-selector@^3.0.0: dependencies: "@types/hast" "^2.0.0" -hast-util-to-html@^8.0.0: - version "8.0.3" - resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-8.0.3.tgz#4e37580872e143ea9ce0dba87918b19e4ea997e3" - integrity sha512-/D/E5ymdPYhHpPkuTHOUkSatxr4w1ZKrZsG0Zv/3C2SRVT0JFJG53VS45AMrBtYk0wp5A7ksEhiC8QaOZM95+A== +hast-util-to-mdast@^8.3.0: + version "8.3.1" + resolved "https://registry.yarnpkg.com/hast-util-to-mdast/-/hast-util-to-mdast-8.3.1.tgz#b2e3b666968d3ab96a0e6ec991cca0ca5c79e3b2" + integrity sha512-nxLcom1oW5y/1CyaV24K16LOfYbAIS74BDbCPW6WduzAYTAVDp3g/DM1CY6Ngo+Dx5itLzvmCm7SnUHBZd3NVQ== dependencies: + "@types/extend" "^3.0.0" "@types/hast" "^2.0.0" - ccount "^2.0.0" - comma-separated-tokens "^2.0.0" + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + extend "^3.0.0" + hast-util-has-property "^2.0.0" hast-util-is-element "^2.0.0" - hast-util-whitespace "^2.0.0" - html-void-elements "^2.0.0" - property-information "^6.0.0" - space-separated-tokens "^2.0.0" - stringify-entities "^4.0.2" + hast-util-to-text "^3.0.0" + mdast-util-phrasing "^3.0.0" + mdast-util-to-string "^3.0.0" + rehype-minify-whitespace "^5.0.0" + trim-trailing-lines "^2.0.0" unist-util-is "^5.0.0" + unist-util-visit "^4.0.0" hast-util-to-string@^2.0.0: version "2.0.0" @@ -1196,7 +1397,7 @@ hast-util-to-string@^2.0.0: dependencies: "@types/hast" "^2.0.0" -hast-util-to-text@^3.1.0: +hast-util-to-text@^3.0.0, hast-util-to-text@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/hast-util-to-text/-/hast-util-to-text-3.1.1.tgz#b7699a75f7a61af6e0befb67660cd78460d96dc6" integrity sha512-7S3mOBxACy8syL45hCn3J7rHqYaXkxRfsX6LXEU5Shz4nt4GxdjtMUtG+T6G/ZLUHd7kslFAf14kAN71bz30xA== @@ -1249,10 +1450,24 @@ hoist-non-react-statics@^3.3.2: dependencies: react-is "^16.7.0" -html-void-elements@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-2.0.1.tgz#29459b8b05c200b6c5ee98743c41b979d577549f" - integrity sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A== +iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +icss-utils@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-3.0.1.tgz#ee70d3ae8cac38c6be5ed91e851b27eed343ad0f" + integrity sha1-7nDTroysOMa+XtkehRsn7tNDrQ8= + dependencies: + postcss "^6.0.2" + +icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== ignore@^4.0.6: version "4.0.6" @@ -1264,6 +1479,16 @@ ignore@^5.2.0: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== +image-size@~0.5.0: + version "0.5.5" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" + integrity sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w= + +immutable@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23" + integrity sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw== + import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -1285,7 +1510,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2: +inherits@2, inherits@^2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -1324,6 +1549,13 @@ is-bigint@^1.0.1: dependencies: has-bigints "^1.0.1" +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-boolean-object@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" @@ -1366,7 +1598,7 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -1434,6 +1666,11 @@ is-weakref@^1.0.1: dependencies: call-bind "^1.0.2" +is-what@^3.14.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.14.1.tgz#e1222f46ddda85dead0fd1c9df131760e77755c1" + integrity sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -1466,6 +1703,11 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + json5@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" @@ -1512,6 +1754,23 @@ language-tags@^1.0.5: dependencies: language-subtag-registry "~0.3.2" +less@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/less/-/less-4.1.2.tgz#6099ee584999750c2624b65f80145f8674e4b4b0" + integrity sha512-EoQp/Et7OSOVu0aJknJOtlXZsnr8XE8KwuzTHOLeVSEx8pVWUICc8Q0VYRHgzyjX78nMEyC/oztWFbgyhtNfDA== + dependencies: + copy-anything "^2.0.1" + parse-node-version "^1.0.1" + tslib "^2.3.0" + optionalDependencies: + errno "^0.1.1" + graceful-fs "^4.1.2" + image-size "~0.5.0" + make-dir "^2.1.0" + mime "^1.4.1" + needle "^2.5.2" + source-map "~0.6.0" + levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -1520,6 +1779,21 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +lilconfig@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.4.tgz#f4507d043d7058b380b6a8f5cb7bcd4b34cee082" + integrity sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA== + +loader-utils@^0.2.16: + version "0.2.17" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" + integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g= + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + object-assign "^4.0.1" + locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -1528,6 +1802,11 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -1538,6 +1817,11 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash@^4.17.20, lodash@^4.17.4: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + longest-streak@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.0.1.tgz#c97315b7afa0e7d9525db9a5a2953651432bdc5d" @@ -1573,6 +1857,14 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + markdown-table@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.2.tgz#9b59eb2c1b22fe71954a65ff512887065a7bb57c" @@ -1587,15 +1879,6 @@ mdast-util-definitions@^5.0.0: "@types/unist" "^2.0.0" unist-util-visit "^3.0.0" -mdast-util-find-and-replace@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-1.1.1.tgz#b7db1e873f96f66588c321f1363069abf607d1b5" - integrity sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA== - dependencies: - escape-string-regexp "^4.0.0" - unist-util-is "^4.0.0" - unist-util-visit-parents "^3.0.0" - mdast-util-find-and-replace@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.1.0.tgz#69728acd250749f8aac6e150e07d1fd15619e829" @@ -1686,6 +1969,14 @@ mdast-util-math@^2.0.0: longest-streak "^3.0.0" mdast-util-to-markdown "^1.3.0" +mdast-util-phrasing@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-phrasing/-/mdast-util-phrasing-3.0.0.tgz#c44fcf6be61a3cb8da54ab2df22320e61d4537ce" + integrity sha512-S+QYsDRLkGi8U7o5JF1agKa/sdP+CNGXXLqC17pdTVL8FHHgQEiwFGa9yE5aYtUxNiFGYoaDy9V1kC85Sz86Gg== + dependencies: + "@types/mdast" "^3.0.0" + unist-util-is "^5.0.0" + mdast-util-to-hast@^12.1.0: version "12.1.1" resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-12.1.1.tgz#89a2bb405eaf3b05eb8bf45157678f35eef5dbca" @@ -2025,6 +2316,11 @@ micromatch@^4.0.4: braces "^3.0.1" picomatch "^2.2.3" +mime@^1.4.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + minimatch@^3.0.4, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -2037,11 +2333,21 @@ minimist@^1.2.0: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +mkdirp@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + mri@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== +mrmime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.0.tgz#14d387f0585a5233d291baba339b063752a2398b" + integrity sha512-a70zx7zFfVO7XpnQ2IX1Myh9yY4UYvfld/dikWRnsXxbyvMcfz+u6UfgNAtH+k2QqtJuzVpv6eLTx1G2+WKZbQ== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -2057,7 +2363,7 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -nanoid@^3.1.30: +nanoid@^3.1.30, nanoid@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== @@ -2067,30 +2373,45 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -next@12.1.0: - version "12.1.0" - resolved "https://registry.yarnpkg.com/next/-/next-12.1.0.tgz#c33d753b644be92fc58e06e5a214f143da61dd5d" - integrity sha512-s885kWvnIlxsUFHq9UGyIyLiuD0G3BUC/xrH0CEnH5lHEWkwQcHOORgbDF0hbrW9vr/7am4ETfX4A7M6DjrE7Q== +needle@^2.5.2: + version "2.9.1" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.9.1.tgz#22d1dffbe3490c2b83e301f7709b6736cd8f2684" + integrity sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ== dependencies: - "@next/env" "12.1.0" + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + +next@^12.1.1-canary.15: + version "12.1.1-canary.15" + resolved "https://registry.yarnpkg.com/next/-/next-12.1.1-canary.15.tgz#a31c99a512b29d98aa0f6d837931d5c7f2aa2c35" + integrity sha512-WjD8zIDkLTiGYdnLbmeLmoNZvf7+UZ6oNxDDDNtddUVvej11AB8d+FmcmEuK7L3P8+5HKp1nZEg6oMxmpX/BzQ== + dependencies: + "@next/env" "12.1.1-canary.15" caniuse-lite "^1.0.30001283" postcss "8.4.5" - styled-jsx "5.0.0" + styled-jsx "5.0.1" use-subscription "1.5.1" optionalDependencies: - "@next/swc-android-arm64" "12.1.0" - "@next/swc-darwin-arm64" "12.1.0" - "@next/swc-darwin-x64" "12.1.0" - "@next/swc-linux-arm-gnueabihf" "12.1.0" - "@next/swc-linux-arm64-gnu" "12.1.0" - "@next/swc-linux-arm64-musl" "12.1.0" - "@next/swc-linux-x64-gnu" "12.1.0" - "@next/swc-linux-x64-musl" "12.1.0" - "@next/swc-win32-arm64-msvc" "12.1.0" - "@next/swc-win32-ia32-msvc" "12.1.0" - "@next/swc-win32-x64-msvc" "12.1.0" + "@next/swc-android-arm-eabi" "12.1.1-canary.15" + "@next/swc-android-arm64" "12.1.1-canary.15" + "@next/swc-darwin-arm64" "12.1.1-canary.15" + "@next/swc-darwin-x64" "12.1.1-canary.15" + "@next/swc-linux-arm-gnueabihf" "12.1.1-canary.15" + "@next/swc-linux-arm64-gnu" "12.1.1-canary.15" + "@next/swc-linux-arm64-musl" "12.1.1-canary.15" + "@next/swc-linux-x64-gnu" "12.1.1-canary.15" + "@next/swc-linux-x64-musl" "12.1.1-canary.15" + "@next/swc-win32-arm64-msvc" "12.1.1-canary.15" + "@next/swc-win32-ia32-msvc" "12.1.1-canary.15" + "@next/swc-win32-x64-msvc" "12.1.1-canary.15" -object-assign@^4.1.1: +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -2157,6 +2478,11 @@ once@^1.3.0: dependencies: wrappy "1" +opener@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" + integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== + optionator@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" @@ -2207,6 +2533,11 @@ parse-entities@^2.0.0: is-decimal "^1.0.0" is-hexadecimal "^1.0.0" +parse-node-version@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + parse5@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" @@ -2242,11 +2573,56 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.2.3: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +postcss-filter-plugins@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/postcss-filter-plugins/-/postcss-filter-plugins-3.0.1.tgz#9d226e946d56542ab7c26123053459a331df545d" + integrity sha512-tRKbW4wWBEkSSFuJtamV2wkiV9rj6Yy7P3Y13+zaynlPEEZt8EgYKn3y/RBpMeIhNmHXFlSdzofml65hD5OafA== + dependencies: + postcss "^6.0.14" + +postcss-icss-keyframes@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/postcss-icss-keyframes/-/postcss-icss-keyframes-0.2.1.tgz#80c4455e0112b0f2f9c3c05ac7515062bb9ff295" + integrity sha1-gMRFXgESsPL5w8Bax1FQYruf8pU= + dependencies: + icss-utils "^3.0.1" + postcss "^6.0.2" + postcss-value-parser "^3.3.0" + +postcss-icss-selectors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/postcss-icss-selectors/-/postcss-icss-selectors-2.0.3.tgz#27fa1afcaab6c602c866cbb298f3218e9bc1c9b3" + integrity sha1-J/oa/Kq2xgLIZsuymPMhjpvBybM= + dependencies: + css-selector-tokenizer "^0.7.0" + generic-names "^1.0.2" + icss-utils "^3.0.1" + lodash "^4.17.4" + postcss "^6.0.2" + +postcss-load-config@^3.0.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-3.1.3.tgz#21935b2c43b9a86e6581a576ca7ee1bde2bd1d23" + integrity sha512-5EYgaM9auHGtO//ljHH+v/aC/TQ5LHXtL7bQajNAUBKUVKiYE8rYpFms7+V26D9FncaGe2zwCoPQsFKb5zF/Hw== + dependencies: + lilconfig "^2.0.4" + yaml "^1.10.2" + +postcss-value-parser@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + postcss@8.4.5: version "8.4.5" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95" @@ -2256,11 +2632,34 @@ postcss@8.4.5: picocolors "^1.0.0" source-map-js "^1.0.1" +postcss@^6.0.14, postcss@^6.0.2: + version "6.0.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" + integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.4.0" + +postcss@^8.3.0: + version "8.4.12" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.12.tgz#1e7de78733b28970fa4743f7da6f3763648b1905" + integrity sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg== + dependencies: + nanoid "^3.3.1" + picocolors "^1.0.0" + source-map-js "^1.0.2" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +prism-react-renderer@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.3.1.tgz#88fc9d0df6bed06ca2b9097421349f8c2f24e30d" + integrity sha512-xUeDMEz074d0zc5y6rxiMp/dlC7C+5IDDlaEUlcBOFE2wddz7hz5PNupb087mPwTt7T9BrFmewObfCBuf/LKwQ== + prismjs@^1.25.0, prismjs@^1.27.0, prismjs@~1.27.0: version "1.27.0" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057" @@ -2287,6 +2686,11 @@ property-information@^6.0.0: resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.1.1.tgz#5ca85510a3019726cb9afed4197b7b8ac5926a22" integrity sha512-hrzC564QIl0r0vy4l6MvRLhafmUowhO/O3KgVSoXIbbA2Sz4j8HGpJc6T2cubRVwMwpdiG/vKGfhT4IixmKN9w== +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -2411,6 +2815,13 @@ react@17.0.2: loose-envify "^1.1.0" object-assign "^4.1.1" +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + refractor@^3.2.0: version "3.6.0" resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.6.0.tgz#ac318f5a0715ead790fcfb0c71f4dd83d977935a" @@ -2470,6 +2881,18 @@ rehype-katex@^6.0.2: unist-util-remove-position "^4.0.0" unist-util-visit "^4.0.0" +rehype-minify-whitespace@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/rehype-minify-whitespace/-/rehype-minify-whitespace-5.0.0.tgz#f3eec0ac94e78adbb868133e64864343ba9fff1f" + integrity sha512-cUkQldYx8jpWM6FZmCkOF/+mev09+5NAtBzUFZgnfXsIoglxo3h6t3S3JbNouiaqIDE6vbpI+GQpOg0xD3Z7kg== + dependencies: + "@types/hast" "^2.0.0" + hast-util-embedded "^2.0.0" + hast-util-is-element "^2.0.0" + hast-util-whitespace "^2.0.0" + unified "^10.0.0" + unist-util-is "^5.0.0" + rehype-parse@^8.0.0: version "8.0.4" resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-8.0.4.tgz#3d17c9ff16ddfef6bbcc8e6a25a99467b482d688" @@ -2480,6 +2903,16 @@ rehype-parse@^8.0.0: parse5 "^6.0.0" unified "^10.0.0" +rehype-remark@^9.1.2: + version "9.1.2" + resolved "https://registry.yarnpkg.com/rehype-remark/-/rehype-remark-9.1.2.tgz#b4ed84d7e692426c3269e72ec477906cec659c05" + integrity sha512-c0fG3/CrJ95zAQ07xqHSkdpZybwdsY7X5dNWvgL2XqLKZuqmG3+vk6kP/4miCnp+R+x/0uKKRSpfXb9aGR8Z5w== + dependencies: + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + hast-util-to-mdast "^8.3.0" + unified "^10.0.0" + rehype-slug@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/rehype-slug/-/rehype-slug-5.0.1.tgz#6e732d0c55b3b1e34187e74b7363fb53229e5f52" @@ -2493,15 +2926,6 @@ rehype-slug@^5.0.1: unified "^10.0.0" unist-util-visit "^4.0.0" -rehype-stringify@^9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/rehype-stringify/-/rehype-stringify-9.0.3.tgz#70e3bd6d4d29e7acf36b802deed350305d2c3c17" - integrity sha512-kWiZ1bgyWlgOxpqD5HnxShKAdXtb2IUljn3hQAhySeak6IOQPPt6DeGnsIh4ixm7yKJWzm8TXFuC/lPfcWHJqw== - dependencies: - "@types/hast" "^2.0.0" - hast-util-to-html "^8.0.0" - unified "^10.0.0" - remark-gfm@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/remark-gfm/-/remark-gfm-3.0.1.tgz#0b180f095e3036545e9dddac0e8df3fa5cfee54f" @@ -2541,11 +2965,21 @@ remark-rehype@^10.0.0: mdast-util-to-hast "^12.1.0" unified "^10.0.0" +reserved-words@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/reserved-words/-/reserved-words-0.1.2.tgz#00a0940f98cd501aeaaac316411d9adc52b31ab1" + integrity sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE= + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + resolve@^1.20.0: version "1.22.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" @@ -2589,6 +3023,25 @@ sade@^1.7.3: dependencies: mri "^1.1.0" +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sass@^1.32.13: + version "1.49.9" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.49.9.tgz#b15a189ecb0ca9e24634bae5d1ebc191809712f9" + integrity sha512-YlYWkkHP9fbwaFRZQRXgDi3mXZShslVmmo+FVK3kHLUELHHEYrCmL1x6IUjC7wLS6VuJSAFXRQS/DxdsC4xL1A== + dependencies: + chokidar ">=3.0.0 <4.0.0" + immutable "^4.0.0" + source-map-js ">=0.6.2 <2.0.0" + +sax@^1.2.4, sax@~1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + scheduler@^0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" @@ -2597,6 +3050,11 @@ scheduler@^0.20.2: loose-envify "^1.1.0" object-assign "^4.1.1" +semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -2630,16 +3088,51 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" +sirv@^1.0.7: + version "1.0.19" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.19.tgz#1d73979b38c7fe91fcba49c85280daa9c2363b49" + integrity sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ== + dependencies: + "@polka/url" "^1.0.0-next.20" + mrmime "^1.0.0" + totalist "^1.0.0" + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -source-map-js@^1.0.1: +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== +source-map-resolve@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + +source-map@^0.6.1, source-map@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + space-separated-tokens@^1.0.0: version "1.1.5" resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" @@ -2680,14 +3173,6 @@ string.prototype.trimstart@^1.0.4: call-bind "^1.0.2" define-properties "^1.1.3" -stringify-entities@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-4.0.2.tgz#13d113dc7449dc8ae4cb22c28883ee3fff8753e3" - integrity sha512-MTxTVcEkorNtBbNpoFJPEh0kKdM6+QbMjLbaxmvaPMmayOXdr/AIVIIJX7FReUVweRBFJfZepK4A4AKgwuFpMQ== - dependencies: - character-entities-html4 "^2.0.0" - character-entities-legacy "^3.0.0" - strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -2712,10 +3197,31 @@ style-to-object@^0.3.0: dependencies: inline-style-parser "0.1.1" -styled-jsx@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.0.tgz#816b4b92e07b1786c6b7111821750e0ba4d26e77" - integrity sha512-qUqsWoBquEdERe10EW8vLp3jT25s/ssG1/qX5gZ4wu15OZpmSMFI2v+fWlRhLfykA5rFtlJ1ME8A8pm/peV4WA== +styled-jsx@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.1.tgz#78fecbbad2bf95ce6cd981a08918ce4696f5fc80" + integrity sha512-+PIZ/6Uk40mphiQJJI1202b+/dYeTVd9ZnMPR80pgiWbjIwvN2zIp4r9et0BgqBuShh48I0gttPlAXA7WVvBxw== + +stylus@^0.54.8: + version "0.54.8" + resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.54.8.tgz#3da3e65966bc567a7b044bfe0eece653e099d147" + integrity sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg== + dependencies: + css-parse "~2.0.0" + debug "~3.1.0" + glob "^7.1.6" + mkdirp "~1.0.4" + safer-buffer "^2.1.2" + sax "~1.2.4" + semver "^6.3.0" + source-map "^0.7.3" + +supports-color@^5.3.0, supports-color@^5.4.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" supports-color@^7.1.0: version "7.2.0" @@ -2746,6 +3252,16 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +totalist@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" + integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== + +trim-trailing-lines@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-2.0.0.tgz#1fdfbc20db6651bed117bc5c736f6cf052bcf421" + integrity sha512-lyJ/STqmYO8k9aWZbodPTrVkRh/50yFwNZ/HxKp/30eM9zf898MgQCG/NxfMnx7fZSKbaEcuZ1V+QgWrXFH6rg== + trough@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/trough/-/trough-2.1.0.tgz#0f7b511a4fde65a46f18477ab38849b22c554876" @@ -2766,7 +3282,7 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.3: +tslib@^2.0.3, tslib@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== @@ -2790,6 +3306,25 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== +typescript-plugin-css-modules@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/typescript-plugin-css-modules/-/typescript-plugin-css-modules-3.4.0.tgz#4ff6905d88028684d1608c05c62cb6346e5548cc" + integrity sha512-2MdjfSg4MGex1csCWRUwKD+MpgnvcvLLr9bSAMemU/QYGqBsXdez0cc06H/fFhLtRoKJjXg6PSTur3Gy1Umhpw== + dependencies: + dotenv "^10.0.0" + icss-utils "^5.1.0" + less "^4.1.1" + lodash.camelcase "^4.3.0" + postcss "^8.3.0" + postcss-filter-plugins "^3.0.1" + postcss-icss-keyframes "^0.2.1" + postcss-icss-selectors "^2.0.3" + postcss-load-config "^3.0.1" + reserved-words "^0.1.2" + sass "^1.32.13" + stylus "^0.54.8" + tsconfig-paths "^3.9.0" + typescript@4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.2.tgz#fe12d2727b708f4eef40f51598b3398baa9611d4" @@ -2838,11 +3373,6 @@ unist-util-generated@^2.0.0: resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-2.0.0.tgz#86fafb77eb6ce9bfa6b663c3f5ad4f8e56a60113" integrity sha512-TiWE6DVtVe7Ye2QxOVW9kqybs6cZexNwTwSMVgkfjEReqy/xwGpAXb99OxktoWwmL+Z+Epb0Dn8/GNDYP1wnUw== -unist-util-is@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" - integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== - unist-util-is@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-5.1.1.tgz#e8aece0b102fa9bc097b0fef8f870c496d4a6236" @@ -2868,14 +3398,6 @@ unist-util-stringify-position@^3.0.0: dependencies: "@types/unist" "^2.0.0" -unist-util-visit-parents@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6" - integrity sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^4.0.0" - unist-util-visit-parents@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz#e83559a4ad7e6048a46b1bdb22614f2f3f4724f2" @@ -2892,15 +3414,6 @@ unist-util-visit-parents@^5.0.0: "@types/unist" "^2.0.0" unist-util-is "^5.0.0" -unist-util-visit@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" - integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^4.0.0" - unist-util-visit-parents "^3.0.0" - unist-util-visit@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-3.1.0.tgz#9420d285e1aee938c7d9acbafc8e160186dbaf7b" @@ -2926,6 +3439,11 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + use-subscription@1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.5.1.tgz#73501107f02fad84c6dd57965beb0b75c68c42d1" @@ -2979,6 +3497,21 @@ web-namespaces@^2.0.0: resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.1.tgz#1010ff7c650eccb2592cebeeaf9a1b253fd40692" integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ== +webpack-bundle-analyzer@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.3.0.tgz#2f3c0ca9041d5ee47fa418693cf56b4a518b578b" + integrity sha512-J3TPm54bPARx6QG8z4cKBszahnUglcv70+N+8gUqv2I5KOFHJbzBiLx+pAp606so0X004fxM7hqRu10MLjJifA== + dependencies: + acorn "^8.0.4" + acorn-walk "^8.0.0" + chalk "^4.1.0" + commander "^6.2.0" + gzip-size "^6.0.0" + lodash "^4.17.20" + opener "^1.5.2" + sirv "^1.0.7" + ws "^7.3.1" + which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" @@ -3007,6 +3540,11 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +ws@^7.3.1: + version "7.5.7" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" + integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== + xtend@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" @@ -3017,6 +3555,11 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + zwitch@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.2.tgz#91f8d0e901ffa3d66599756dde7f57b17c95dce1" diff --git a/server/lib/config.ts b/server/src/lib/config.ts similarity index 100% rename from server/lib/config.ts rename to server/src/lib/config.ts diff --git a/server/lib/middleware/jwt.ts b/server/src/lib/middleware/jwt.ts similarity index 100% rename from server/lib/middleware/jwt.ts rename to server/src/lib/middleware/jwt.ts diff --git a/server/src/lib/middleware/secret-key.ts b/server/src/lib/middleware/secret-key.ts new file mode 100644 index 00000000..241fe647 --- /dev/null +++ b/server/src/lib/middleware/secret-key.ts @@ -0,0 +1,14 @@ +import { NextFunction, Request, Response } from 'express'; + +const key = process.env.SECRET_KEY; +if (!key) { + throw new Error('SECRET_KEY is not set.'); +} + +export default function authenticateToken(req: Request, res: Response, next: NextFunction) { + const requestKey = req.headers['x-secret-key'] + if (requestKey !== key) { + return res.sendStatus(401) + } + next() +} diff --git a/server/lib/models/File.ts b/server/src/lib/models/File.ts similarity index 100% rename from server/lib/models/File.ts rename to server/src/lib/models/File.ts diff --git a/server/lib/models/Post.ts b/server/src/lib/models/Post.ts similarity index 92% rename from server/lib/models/Post.ts rename to server/src/lib/models/Post.ts index 7dab48dd..2be1b024 100644 --- a/server/lib/models/Post.ts +++ b/server/src/lib/models/Post.ts @@ -38,7 +38,7 @@ export class Post extends Model { @BelongsToMany(() => User, () => PostAuthor) users?: User[]; - @HasMany(() => File) + @HasMany(() => File, { constraints: false }) files?: File[]; @CreatedAt @@ -48,6 +48,9 @@ export class Post extends Model { @Column visibility!: string; + @Column + password?: string; + @UpdatedAt @Column updatedAt!: Date; diff --git a/server/lib/models/PostAuthor.ts b/server/src/lib/models/PostAuthor.ts similarity index 100% rename from server/lib/models/PostAuthor.ts rename to server/src/lib/models/PostAuthor.ts diff --git a/server/lib/models/User.ts b/server/src/lib/models/User.ts similarity index 100% rename from server/lib/models/User.ts rename to server/src/lib/models/User.ts diff --git a/server/lib/sequelize.ts b/server/src/lib/sequelize.ts similarity index 100% rename from server/lib/sequelize.ts rename to server/src/lib/sequelize.ts diff --git a/server/src/routes/auth.ts b/server/src/routes/auth.ts index 049445c0..9e77a93a 100644 --- a/server/src/routes/auth.ts +++ b/server/src/routes/auth.ts @@ -1,9 +1,9 @@ import { Router } from 'express' import { genSalt, hash, compare } from "bcrypt" -import { User } from '../../lib/models/User' +import { User } from '../lib/models/User' import { sign } from 'jsonwebtoken' -import config from '../../lib/config' -import jwt from '../../lib/middleware/jwt' +import config from '../lib/config' +import jwt from '../lib/middleware/jwt' const NO_EMPTY_SPACE_REGEX = /^\S*$/ diff --git a/server/src/routes/files.ts b/server/src/routes/files.ts index 7a23751a..70a43cde 100644 --- a/server/src/routes/files.ts +++ b/server/src/routes/files.ts @@ -1,10 +1,10 @@ import { Router } from 'express' -// import { Movie } from '../models/Post' -import { File } from '../../lib/models/File' +import secretKey from '../lib/middleware/secret-key'; +import { File } from '../lib/models/File' export const files = Router() -files.get("/raw/:id", async (req, res, next) => { +files.get("/raw/:id", secretKey, async (req, res, next) => { try { const file = await File.findOne({ where: { @@ -12,18 +12,18 @@ files.get("/raw/:id", async (req, res, next) => { }, attributes: ["title", "content"], }) - // TODO: fix post inclusion - // if (file?.post.visibility === 'public' || file?.post.visibility === 'unlisted') { - res.setHeader("Cache-Control", "public, max-age=86400"); - res.json(file); - // } else { - // TODO: should this be `private, `? - // res.setHeader("Cache-Control", "max-age=86400"); - // res.json(file); - // } + + // TODO: JWT-checkraw files + if (file?.post?.visibility === "private") { + // jwt(req as UserJwtRequest, res, () => { + // res.json(file); + // }) + res.json(file); + } else { + res.json(file); + } } catch (e) { next(e); } }); - diff --git a/server/src/routes/posts.ts b/server/src/routes/posts.ts index a528f310..fde52b6b 100644 --- a/server/src/routes/posts.ts +++ b/server/src/routes/posts.ts @@ -1,10 +1,11 @@ import { Router } from 'express' // import { Movie } from '../models/Post' -import { File } from '../../lib/models/File' -import { Post } from '../../lib/models/Post'; -import jwt, { UserJwtRequest } from '../../lib/middleware/jwt'; +import { File } from '../lib/models/File' +import { Post } from '../lib/models/Post'; +import jwt, { UserJwtRequest } from '../lib/middleware/jwt'; import * as crypto from "crypto"; -import { User } from '../../lib/models/User'; +import { User } from '../lib/models/User'; +import secretKey from '../lib/middleware/secret-key'; export const posts = Router() @@ -26,7 +27,6 @@ posts.post('/create', jwt, async (req, res, next) => { throw new Error("Please provide a visibility.") } - // Create the "post" object const newPost = new Post({ title: req.body.title, visibility: req.body.visibility, @@ -35,7 +35,6 @@ posts.post('/create', jwt, async (req, res, next) => { await newPost.save() await newPost.$add('users', req.body.userId); const newFiles = await Promise.all(req.body.files.map(async (file) => { - // Establish a "file" for each file in the request const newFile = new File({ title: file.title, content: file.content, @@ -59,7 +58,47 @@ posts.post('/create', jwt, async (req, res, next) => { } }); -posts.get("/:id", async (req: UserJwtRequest, res, next) => { +posts.get("/", secretKey, async (req, res, next) => { + try { + const posts = await Post.findAll({ + attributes: ["id", "title", "visibility", "createdAt"], + }) + res.json(posts); + } catch (e) { + next(e); + } +}); + +posts.get("/mine", jwt, secretKey, async (req: UserJwtRequest, res, next) => { + if (!req.user) { + return res.status(401).json({ error: "Unauthorized" }) + } + + try { + const user = await User.findByPk(req.user.id, { + include: [ + { + model: Post, + as: "posts", + include: [ + { + model: File, + as: "files" + } + ] + }, + ], + }) + if (!user) { + return res.status(404).json({ error: "User not found" }) + } + return res.json(user.posts?.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())) + } catch (error) { + next(error) + } +}) + +posts.get("/:id", secretKey, async (req, res, next) => { try { const post = await Post.findOne({ where: { @@ -78,20 +117,21 @@ posts.get("/:id", async (req: UserJwtRequest, res, next) => { }, ] }) + if (!post) { + throw new Error("Post not found.") + } - if (post?.visibility === 'public' || post?.visibility === 'unlisted') { - res.setHeader("Cache-Control", "public, max-age=86400"); + if (post.visibility === 'public' || post?.visibility === 'unlisted') { res.json(post); - } else { - // TODO: should this be `private, `? - res.setHeader("Cache-Control", "max-age=86400"); - jwt(req, res, () => { + } else if (post.visibility === 'private') { + jwt(req as UserJwtRequest, res, () => { res.json(post); - }); + }) + } else if (post.visibility === 'protected') { + } } catch (e) { next(e); } }); - diff --git a/server/src/routes/users.ts b/server/src/routes/users.ts index 3ffefd01..aedcd1e1 100644 --- a/server/src/routes/users.ts +++ b/server/src/routes/users.ts @@ -1,9 +1,7 @@ import { Router } from 'express' // import { Movie } from '../models/Post' -import { User } from '../../lib/models/User' -import { File } from '../../lib/models/File' -import jwt, { UserJwtRequest } from '../../lib/middleware/jwt' -import { Post } from '../../lib/models/Post' +import { User } from '../lib/models/User' +import jwt from '../lib/middleware/jwt' export const users = Router() @@ -16,31 +14,3 @@ users.get('/', jwt, async (req, res, next) => { } }) -users.get("/mine", jwt, async (req: UserJwtRequest, res, next) => { - if (!req.user) { - return res.status(401).json({ error: "Unauthorized" }) - } - - try { - const user = await User.findByPk(req.user.id, { - include: [ - { - model: Post, - as: "posts", - include: [ - { - model: File, - as: "files" - } - ] - }, - ], - }) - if (!user) { - return res.status(404).json({ error: "User not found" }) - } - return res.json(user.posts?.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())) - } catch (error) { - next(error) - } -}) diff --git a/server/src/server.ts b/server/src/server.ts index 2e96ea8d..b3670024 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -1,7 +1,7 @@ import { createServer } from 'http'; import { app } from './app'; -import config from '../lib/config'; -import { sequelize } from '../lib/sequelize'; +import config from './lib/config'; +import { sequelize } from './lib/sequelize'; (async () => { await sequelize.sync(); diff --git a/server/tsconfig.json b/server/tsconfig.json index e5fbe651..765d8a8c 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -15,6 +15,6 @@ "strictPropertyInitialization": true, "outDir": "dist" }, - "include": ["lib/**/*.ts", "index.ts", "src/**/*.ts"], + "include": ["index.ts", "src/**/*.ts"], "exclude": ["node_modules"] }