From b9567ca3c27dea7e507ea27d62e7b10a98e2ee53 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 28 Mar 2023 11:01:50 +0330 Subject: [PATCH] many breaking changes/fixes --- components/CollectionCard.tsx | 5 +- .../InputSelect/CollectionSelection.tsx | 22 +- components/InputSelect/TagSelection.tsx | 11 +- components/LinkList.tsx | 56 +- .../{AddLinkModal.tsx => Modal/AddLink.tsx} | 67 +- components/Modal/EditLink.tsx | 101 +++ components/Modal/index.tsx | 19 + components/Navbar.tsx | 164 +++-- components/Sidebar/index.tsx | 69 +-- layouts/MainLayout.tsx | 17 +- lib/api/archive.ts | 71 ++- .../controllers/collections/getCollections.ts | 14 +- .../controllers/collections/postCollection.ts | 40 +- lib/api/controllers/links/deleteLink.ts | 30 +- lib/api/controllers/links/getLinks.ts | 19 +- lib/api/controllers/links/postLink.ts | 124 ++-- lib/api/controllers/tags/getTags.ts | 27 +- package.json | 5 +- pages/_app.tsx | 23 + pages/api/auth/[...nextauth].ts | 2 + pages/api/routes/collections/index.ts | 26 +- pages/api/routes/links/index.ts | 26 +- pages/api/routes/tags/index.ts | 5 +- pages/collections/[id].tsx | 5 +- pages/collections/index.tsx | 54 +- pages/links.tsx | 14 + pages/login.tsx | 2 + .../migration.sql | 2 - .../migration.sql | 11 +- .../20230328031049_init/migration.sql | 2 + .../migrations/20230328072406_/migration.sql | 11 + prisma/schema.prisma | 11 +- public/android-chrome-192x192.png | Bin 0 -> 7020 bytes public/android-chrome-512x512.png | Bin 0 -> 23412 bytes public/apple-touch-icon.png | Bin 0 -> 6896 bytes public/favicon-16x16.png | Bin 0 -> 402 bytes public/favicon-32x32.png | Bin 0 -> 767 bytes public/favicon.ico | Bin 25931 -> 15406 bytes public/icon.png | Bin 0 -> 21476 bytes public/site.webmanifest | 1 + store/links.ts | 8 +- types/global.ts | 7 +- yarn.lock | 575 +++++++++++++++++- 43 files changed, 1180 insertions(+), 466 deletions(-) rename components/{AddLinkModal.tsx => Modal/AddLink.tsx} (60%) create mode 100644 components/Modal/EditLink.tsx create mode 100644 components/Modal/index.tsx create mode 100644 pages/links.tsx delete mode 100644 prisma/migrations/20230322214726_renamed_is_favorite_to_starred/migration.sql rename prisma/migrations/{20230312184928_init => 20230327225044_init}/migration.sql (88%) create mode 100644 prisma/migrations/20230328031049_init/migration.sql create mode 100644 prisma/migrations/20230328072406_/migration.sql create mode 100644 public/android-chrome-192x192.png create mode 100644 public/android-chrome-512x512.png create mode 100644 public/apple-touch-icon.png create mode 100644 public/favicon-16x16.png create mode 100644 public/favicon-32x32.png create mode 100644 public/icon.png create mode 100644 public/site.webmanifest diff --git a/components/CollectionCard.tsx b/components/CollectionCard.tsx index b9efac6..cad3db7 100644 --- a/components/CollectionCard.tsx +++ b/components/CollectionCard.tsx @@ -15,7 +15,10 @@ export default function ({ collection }: { collection: Collection }) {

{collection.name}

- +

{formattedDate}

diff --git a/components/InputSelect/CollectionSelection.tsx b/components/InputSelect/CollectionSelection.tsx index aa5be0d..b14a658 100644 --- a/components/InputSelect/CollectionSelection.tsx +++ b/components/InputSelect/CollectionSelection.tsx @@ -5,7 +5,17 @@ import CreatableSelect from "react-select/creatable"; import { styles } from "./styles"; import { Options } from "./types"; -export default function ({ onChange }: any) { +type Props = { + onChange: any; + defaultValue: + | { + value: number; + label: string; + } + | undefined; +}; + +export default function ({ onChange, defaultValue }: Props) { const { collections } = useCollectionStore(); const router = useRouter(); @@ -17,10 +27,8 @@ export default function ({ onChange }: any) { return e.id === collectionId; }); - let defaultCollection = null; - - if (activeCollection) { - defaultCollection = { + if (activeCollection && !defaultValue) { + defaultValue = { value: activeCollection?.id, label: activeCollection?.name, }; @@ -28,7 +36,7 @@ export default function ({ onChange }: any) { useEffect(() => { const formatedCollections = collections.map((e) => { - return { value: e.id, label: e.name }; + return { value: e.id, label: e.name, ownerId: e.ownerId }; }); setOptions(formatedCollections); @@ -40,7 +48,7 @@ export default function ({ onChange }: any) { onChange={onChange} options={options} styles={styles} - defaultValue={defaultCollection} + defaultValue={defaultValue} menuPosition="fixed" /> ); diff --git a/components/InputSelect/TagSelection.tsx b/components/InputSelect/TagSelection.tsx index 87ac38b..819c9ae 100644 --- a/components/InputSelect/TagSelection.tsx +++ b/components/InputSelect/TagSelection.tsx @@ -4,7 +4,15 @@ import CreatableSelect from "react-select/creatable"; import { styles } from "./styles"; import { Options } from "./types"; -export default function ({ onChange }: any) { +type Props = { + onChange: any; + defaultValue?: { + value: number; + label: string; + }[]; +}; + +export default function ({ onChange, defaultValue }: Props) { const { tags } = useTagStore(); const [options, setOptions] = useState([]); @@ -23,6 +31,7 @@ export default function ({ onChange }: any) { onChange={onChange} options={options} styles={styles} + defaultValue={defaultValue} menuPosition="fixed" isMulti /> diff --git a/components/LinkList.tsx b/components/LinkList.tsx index b513a26..0dd5a0c 100644 --- a/components/LinkList.tsx +++ b/components/LinkList.tsx @@ -3,17 +3,17 @@ import { faFolder, faArrowUpRightFromSquare, faEllipsis, - faStar, faPenToSquare, faTrashCan, } from "@fortawesome/free-solid-svg-icons"; import { faFileImage, faFilePdf } from "@fortawesome/free-regular-svg-icons"; - import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useState } from "react"; import Image from "next/image"; import Dropdown from "./Dropdown"; import useLinkStore from "@/store/links"; +import Modal from "./Modal"; +import EditLink from "./Modal/EditLink"; export default function ({ link, @@ -23,6 +23,7 @@ export default function ({ count: number; }) { const [editDropdown, setEditDropdown] = useState(false); + const [editModal, setEditModal] = useState(false); const [archiveLabel, setArchiveLabel] = useState("Archived Formats"); const { removeLink } = useLinkStore(); @@ -34,14 +35,24 @@ export default function ({ day: "numeric", }); + const toggleEditModal = () => { + setEditModal(!editModal); + }; + return ( -
+
+ {editModal ? ( + + + + ) : null} + { const target = e.target as HTMLElement; @@ -53,7 +64,7 @@ export default function ({ width={80} height={80} alt="" - className="blur-sm absolute left-0 opacity-50 select-none" + className="blur-sm absolute left-2 opacity-50 select-none hidden sm:block" draggable="false" onError={(e) => { const target = e.target as HTMLElement; @@ -65,9 +76,6 @@ export default function ({

{count + 1}.

{link.name}

- {link.starred ? ( - - ) : null}

{link.title}

@@ -101,20 +109,25 @@ export default function ({
- setEditDropdown(!editDropdown)} id="edit-dropdown" - /> + className="text-gray-500 inline-flex rounded-md cursor-pointer hover:bg-white hover:outline outline-sky-100 outline-1 duration-100 p-1" + > + +

{archiveLabel}

diff --git a/components/AddLinkModal.tsx b/components/Modal/AddLink.tsx similarity index 60% rename from components/AddLinkModal.tsx rename to components/Modal/AddLink.tsx index d4f8519..a803d2d 100644 --- a/components/AddLinkModal.tsx +++ b/components/Modal/AddLink.tsx @@ -1,46 +1,76 @@ -import React, { useState } from "react"; -import CollectionSelection from "./InputSelect/CollectionSelection"; -import TagSelection from "./InputSelect/TagSelection"; +import React, { useEffect, useState } from "react"; +import CollectionSelection from "@/components/InputSelect/CollectionSelection"; +import TagSelection from "@/components/InputSelect/TagSelection"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faPlus } from "@fortawesome/free-solid-svg-icons"; -import { useRouter } from "next/router"; -import { NewLink } from "@/types/global"; +import { ExtendedLink, NewLink } from "@/types/global"; import useLinkStore from "@/store/links"; +import { useRouter } from "next/router"; +import useCollectionStore from "@/store/collections"; -export default function ({ toggleLinkModal }: { toggleLinkModal: Function }) { +type Props = { + toggleLinkModal: Function; +}; + +export default function AddLink({ toggleLinkModal }: Props) { const router = useRouter(); - const [newLink, setNewLink] = useState({ name: "", url: "", tags: [], - collection: { id: Number(router.query.id) }, + collection: { + id: undefined, + name: "", + ownerId: undefined, + }, }); const { addLink } = useLinkStore(); + const { collections } = useCollectionStore(); + + useEffect(() => { + if (router.query.id) { + const currentCollection = collections.find( + (e) => e.id == Number(router.query.id) + ); + + setNewLink({ + ...newLink, + collection: { + id: currentCollection?.id, + name: currentCollection?.name, + ownerId: currentCollection?.ownerId, + }, + }); + } + }, []); const setTags = (e: any) => { const tagNames = e.map((e: any) => { - return e.label; + return { name: e.label }; }); setNewLink({ ...newLink, tags: tagNames }); }; const setCollection = (e: any) => { - const collection = { id: e?.value, isNew: e?.__isNew__ }; + if (e?.__isNew__) e.value = null; - setNewLink({ ...newLink, collection: collection }); + setNewLink({ + ...newLink, + collection: { id: e?.value, name: e?.label, ownerId: e?.ownerId }, + }); }; const submitLink = async () => { - const response = await addLink(newLink); + console.log(newLink); + + const response = await addLink(newLink as ExtendedLink); if (response) toggleLinkModal(); }; - return ( -
+

New Link

@@ -72,7 +102,14 @@ export default function ({ toggleLinkModal }: { toggleLinkModal: Function }) {

Collection

- +
(link); + + const { updateLink } = useLinkStore(); + + const setTags = (e: any) => { + const tagNames = e.map((e: any) => { + return { name: e.label }; + }); + + setCurrentLink({ ...currentLink, tags: tagNames }); + }; + + const setCollection = (e: any) => { + if (e?.__isNew__) e.value = null; + + setCurrentLink({ + ...currentLink, + collection: { id: e?.value, name: e?.label, ownerId: e?.ownerId } as any, + }); + }; + + const submitLink = async () => { + updateLink(currentLink); + toggleLinkModal(); + }; + + return ( +
+

New Link

+ +
+

Name

+ + setCurrentLink({ ...currentLink, name: e.target.value }) + } + type="text" + placeholder="e.g. Example Link" + className="w-60 rounded-md p-3 border-sky-100 border-solid border text-sm outline-none focus:border-sky-500 duration-100" + /> +
+ +
+

URL

+ + setCurrentLink({ ...currentLink, url: e.target.value }) + } + type="text" + placeholder="e.g. http://example.com/" + className="w-60 rounded-md p-3 border-sky-100 border-solid border text-sm outline-none focus:border-sky-500 duration-100" + /> +
+ +
+

Tags

+ { + return { label: e.name, value: e.id }; + })} + /> +
+ +
+

Collection

+ +
+ +
+ + Edit Link +
+
+ ); +} diff --git a/components/Modal/index.tsx b/components/Modal/index.tsx new file mode 100644 index 0000000..915a80d --- /dev/null +++ b/components/Modal/index.tsx @@ -0,0 +1,19 @@ +import { ReactNode } from "react"; +import ClickAwayHandler from "@/components/ClickAwayHandler"; + +type Props = { + toggleModal: Function; + children: ReactNode; +}; + +export default function ({ toggleModal, children }: Props) { + return ( +
+ +
+ {children} +
+
+
+ ); +} diff --git a/components/Navbar.tsx b/components/Navbar.tsx index c5aa529..5abe047 100644 --- a/components/Navbar.tsx +++ b/components/Navbar.tsx @@ -1,62 +1,25 @@ -import { useRouter } from "next/router"; -import useCollectionStore from "@/store/collections"; -import { Collection, Tag } from "@prisma/client"; -import ClickAwayHandler from "./ClickAwayHandler"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { signOut } from "next-auth/react"; +import { useSession } from "next-auth/react"; import { faPlus, - faFolder, - faBox, - faHashtag, - faBookmark, faMagnifyingGlass, - IconDefinition, + faCircleUser, + faSliders, + faArrowRightFromBracket, + faChevronDown, } from "@fortawesome/free-solid-svg-icons"; -import { useEffect, useState } from "react"; -import AddLinkModal from "./AddLinkModal"; -import useTagStore from "@/store/tags"; +import { useState } from "react"; +import Dropdown from "@/components/Dropdown"; +import Modal from "./Modal"; +import AddLink from "./Modal/AddLink"; export default function () { - const router = useRouter(); - const [pageName, setPageName] = useState(""); - const [pageIcon, setPageIcon] = useState(null); + const { data: session } = useSession(); - const { collections } = useCollectionStore(); - const { tags } = useTagStore(); + const [profileDropdown, setProfileDropdown] = useState(false); - useEffect(() => { - if (router.route === "/collections/[id]") { - const collectionId = router.query.id; - - const activeCollection: Collection | undefined = collections.find( - (e) => e.id.toString() == collectionId - ); - - if (activeCollection) { - setPageName(activeCollection?.name); - } - - setPageIcon(faFolder); - } else if (router.route === "/tags/[id]") { - const tagId = router.query.id; - - const activeTag: Tag | undefined = tags.find( - (e) => e.id.toString() == tagId - ); - - if (activeTag) { - setPageName(activeTag?.name); - } - - setPageIcon(faHashtag); - } else if (router.route === "/collections") { - setPageName("All Collections"); - setPageIcon(faBox); - } else if (router.route === "/links") { - setPageName("All Links"); - setPageIcon(faBookmark); - } - }, [router, collections, tags]); + const user = session?.user; const [linkModal, setLinkModal] = useState(false); @@ -65,50 +28,75 @@ export default function () { }; return ( -
-
- {pageIcon ? ( - - ) : null} -

{pageName}

+
+
+ +
- -
-
- - -
- +
+ className="inline-flex gap-1 items-center select-none cursor-pointer p-1 text-sky-500 rounded-md hover:outline-sky-500 outline duration-100 bg-white outline-sky-100 outline-1" + > + +
{linkModal ? ( -
- - - -
+ + + ) : null} + +
+
setProfileDropdown(!profileDropdown)} + id="profile-dropdown" + > + +
+

{user?.name}

+ +
+
+ {profileDropdown ? ( + , + }, + { + name: "Logout", + icon: , + onClick: () => { + signOut(); + setProfileDropdown(!profileDropdown); + }, + }, + ]} + onClickOutside={(e: Event) => { + const target = e.target as HTMLInputElement; + if (target.id !== "profile-dropdown") setProfileDropdown(false); + }} + className="absolute top-8 right-0 z-20" + /> + ) : null} +
); diff --git a/components/Sidebar/index.tsx b/components/Sidebar/index.tsx index de03dd1..d4566e3 100644 --- a/components/Sidebar/index.tsx +++ b/components/Sidebar/index.tsx @@ -1,37 +1,25 @@ -import { useSession } from "next-auth/react"; import ClickAwayHandler from "@/components/ClickAwayHandler"; import { useState } from "react"; import useCollectionStore from "@/store/collections"; -import { signOut } from "next-auth/react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faPlus, - faChevronDown, faFolder, faBox, faHashtag, faBookmark, - faCircleUser, - faSliders, - faArrowRightFromBracket, } from "@fortawesome/free-solid-svg-icons"; import SidebarItem from "./SidebarItem"; import useTagStore from "@/store/tags"; import Link from "next/link"; -import Dropdown from "@/components/Dropdown"; export default function () { - const { data: session } = useSession(); - const [collectionInput, setCollectionInput] = useState(false); - const [profileDropdown, setProfileDropdown] = useState(false); const { collections, addCollection } = useCollectionStore(); const { tags } = useTagStore(); - const user = session?.user; - const toggleCollectionInput = () => { setCollectionInput(!collectionInput); }; @@ -48,48 +36,12 @@ export default function () { }; return ( -
-
-
setProfileDropdown(!profileDropdown)} - id="profile-dropdown" - > - -
-

{user?.name}

- -
-
- {profileDropdown ? ( - , - }, - { - name: "Logout", - icon: , - onClick: () => { - signOut(); - setProfileDropdown(!profileDropdown); - }, - }, - ]} - onClickOutside={(e: Event) => { - const target = e.target as HTMLInputElement; - if (target.id !== "profile-dropdown") setProfileDropdown(false); - }} - className="absolute top-10 left-0" - /> - ) : null} -
+
+

+ Linkwarden +

- +

All Links

@@ -119,12 +71,13 @@ export default function () { /> ) : ( - + onClick={toggleCollectionInput} + className="select-none text-gray-500 rounded-md cursor-pointer hover:bg-white hover:outline outline-sky-100 outline-1 duration-100 p-1" + > + +
)}
diff --git a/layouts/MainLayout.tsx b/layouts/MainLayout.tsx index e41ab6d..4ddb3ab 100644 --- a/layouts/MainLayout.tsx +++ b/layouts/MainLayout.tsx @@ -1,4 +1,3 @@ -import Head from "next/head"; import Navbar from "@/components/Navbar"; import Sidebar from "@/components/Sidebar"; import { ReactNode } from "react"; @@ -23,11 +22,6 @@ export default function ({ children }: Props) { if (status === "authenticated" && !redirection && routeExists) return ( <> - - Linkwarden - - -
@@ -36,15 +30,6 @@ export default function ({ children }: Props) { ); else if ((status === "unauthenticated" && !redirection) || !routeExists) - return ( - <> - - Linkwarden - - - - {children} - - ); + return <>{children}; else return ; } diff --git a/lib/api/archive.ts b/lib/api/archive.ts index b4f12f5..496a464 100644 --- a/lib/api/archive.ts +++ b/lib/api/archive.ts @@ -1,31 +1,62 @@ -import { chromium, devices } from "playwright"; +import { Page } from "puppeteer"; import { prisma } from "@/lib/api/db"; +import puppeteer from "puppeteer-extra"; +import AdblockerPlugin from "puppeteer-extra-plugin-adblocker"; +import StealthPlugin from "puppeteer-extra-plugin-stealth"; export default async (url: string, collectionId: number, linkId: number) => { const archivePath = `data/archives/${collectionId}/${linkId}`; - const browser = await chromium.launch(); - const context = await browser.newContext(devices["Desktop Chrome"]); - const page = await context.newPage(); + const browser = await puppeteer.launch(); - // const contexts = browser.contexts(); - // console.log(contexts.length); + try { + puppeteer.use(AdblockerPlugin()).use(StealthPlugin()); - await page.goto(url); + const page = await browser.newPage(); - const linkExists = await prisma.link.findFirst({ - where: { - id: linkId, - }, - }); + await page.goto(url, { waitUntil: "domcontentloaded", timeout: 300000 }); - if (linkExists) { - await Promise.all([ - page.pdf({ path: archivePath + ".pdf" }), - page.screenshot({ fullPage: true, path: archivePath + ".png" }), - ]); + await page.setViewport({ width: 1080, height: 1024 }); + + await autoScroll(page); + + const linkExists = await prisma.link.findFirst({ + where: { + id: linkId, + }, + }); + + if (linkExists) { + await Promise.all([ + page.pdf({ path: archivePath + ".pdf", format: "a4" }), + page.screenshot({ fullPage: true, path: archivePath + ".png" }), + ]); + } + + await browser.close(); + } catch (err) { + console.log(err); + await browser.close(); } - - await context.close(); - await browser.close(); +}; + +const autoScroll = async (page: Page) => { + await page.evaluate(async () => { + await new Promise((resolve, reject) => { + let totalHeight = 0; + let distance = 100; + let scrollDown = setInterval(() => { + let scrollHeight = document.body.scrollHeight; + window.scrollBy(0, distance); + totalHeight += distance; + if (totalHeight >= scrollHeight) { + clearInterval(scrollDown); + window.scroll(0, 0); + resolve(); + } + }, 100); + }); + + await new Promise((r) => setTimeout(r, 2000)); + }); }; diff --git a/lib/api/controllers/collections/getCollections.ts b/lib/api/controllers/collections/getCollections.ts index 7e668b5..110cd41 100644 --- a/lib/api/controllers/collections/getCollections.ts +++ b/lib/api/controllers/collections/getCollections.ts @@ -1,19 +1,11 @@ -import type { NextApiRequest, NextApiResponse } from "next"; import { prisma } from "@/lib/api/db"; -import { Session } from "next-auth"; -export default async function ( - req: NextApiRequest, - res: NextApiResponse, - session: Session -) { +export default async function (userId: number) { const collections = await prisma.collection.findMany({ where: { - ownerId: session?.user.id, + ownerId: userId, }, }); - return res.status(200).json({ - response: collections || [], - }); + return { response: collections, status: 200 }; } diff --git a/lib/api/controllers/collections/postCollection.ts b/lib/api/controllers/collections/postCollection.ts index d938755..d8dc865 100644 --- a/lib/api/controllers/collections/postCollection.ts +++ b/lib/api/controllers/collections/postCollection.ts @@ -1,29 +1,16 @@ -import type { NextApiRequest, NextApiResponse } from "next"; import { prisma } from "@/lib/api/db"; -import { Session } from "next-auth"; import { existsSync, mkdirSync } from "fs"; -export default async function ( - req: NextApiRequest, - res: NextApiResponse, - session: Session -) { - if (!session?.user?.email) { - return res.status(401).json({ response: "You must be logged in." }); - } +export default async function (collectionName: string, userId: number) { + if (!collectionName) + return { + response: "Please enter a valid name for the collection.", + status: 400, + }; - const email: string = session.user.email; - const collectionName: string = req?.body?.collectionName; - - if (!collectionName) { - return res - .status(401) - .json({ response: "Please enter a valid name for the collection." }); - } - - const findCollection = await prisma.user.findFirst({ + const findCollection = await prisma.user.findUnique({ where: { - email, + id: userId, }, select: { collections: { @@ -36,15 +23,14 @@ export default async function ( const checkIfCollectionExists = findCollection?.collections[0]; - if (checkIfCollectionExists) { - return res.status(400).json({ response: "Collection already exists." }); - } + if (checkIfCollectionExists) + return { response: "Collection already exists.", status: 400 }; const newCollection = await prisma.collection.create({ data: { owner: { connect: { - id: session.user.id, + id: userId, }, }, name: collectionName, @@ -55,7 +41,5 @@ export default async function ( if (!existsSync(collectionPath)) mkdirSync(collectionPath, { recursive: true }); - return res.status(200).json({ - response: newCollection, - }); + return { response: newCollection, status: 200 }; } diff --git a/lib/api/controllers/links/deleteLink.ts b/lib/api/controllers/links/deleteLink.ts index 15f119e..54b1e28 100644 --- a/lib/api/controllers/links/deleteLink.ts +++ b/lib/api/controllers/links/deleteLink.ts @@ -1,37 +1,23 @@ -import type { NextApiRequest, NextApiResponse } from "next"; import { prisma } from "@/lib/api/db"; -import { Session } from "next-auth"; import { ExtendedLink } from "@/types/global"; import fs from "fs"; import { Link, UsersAndCollections } from "@prisma/client"; import hasAccessToCollection from "@/lib/api/hasAccessToCollection"; -export default async function ( - req: NextApiRequest, - res: NextApiResponse, - session: Session -) { - if (!session?.user?.email) { - return res.status(401).json({ response: "You must be logged in." }); - } - - const link: ExtendedLink = req?.body; - - if (!link) { - return res.status(401).json({ response: "Please choose a valid link." }); - } +export default async function (link: ExtendedLink, userId: number) { + if (!link) return { response: "Please choose a valid link.", status: 401 }; const collectionIsAccessible = await hasAccessToCollection( - session.user.id, + userId, link.collectionId ); const memberHasAccess = collectionIsAccessible?.members.some( - (e: UsersAndCollections) => e.userId === session.user.id && e.canDelete + (e: UsersAndCollections) => e.userId === userId && e.canDelete ); - if (!(collectionIsAccessible?.ownerId === session.user.id || memberHasAccess)) - return res.status(401).json({ response: "Collection is not accessible." }); + if (!(collectionIsAccessible?.ownerId === userId || memberHasAccess)) + return { response: "Collection is not accessible.", status: 401 }; const deleteLink: Link = await prisma.link.delete({ where: { @@ -47,7 +33,5 @@ export default async function ( if (err) console.log(err); }); - return res.status(200).json({ - response: deleteLink, - }); + return { response: deleteLink, status: 200 }; } diff --git a/lib/api/controllers/links/getLinks.ts b/lib/api/controllers/links/getLinks.ts index bf07860..12ee450 100644 --- a/lib/api/controllers/links/getLinks.ts +++ b/lib/api/controllers/links/getLinks.ts @@ -1,23 +1,16 @@ -import type { NextApiRequest, NextApiResponse } from "next"; import { prisma } from "@/lib/api/db"; -import { Session } from "next-auth"; - -export default async function ( - req: NextApiRequest, - res: NextApiResponse, - session: Session -) { - const tags = await prisma.link.findMany({ +export default async function (userId: number) { + const links = await prisma.link.findMany({ where: { collection: { OR: [ { - ownerId: session?.user.id, + ownerId: userId, }, { members: { some: { - userId: session?.user.id, + userId, }, }, }, @@ -30,7 +23,5 @@ export default async function ( }, }); - return res.status(200).json({ - response: tags || [], - }); + return { response: links, status: 200 }; } diff --git a/lib/api/controllers/links/postLink.ts b/lib/api/controllers/links/postLink.ts index 2994843..f184b97 100644 --- a/lib/api/controllers/links/postLink.ts +++ b/lib/api/controllers/links/postLink.ts @@ -1,7 +1,5 @@ -import type { NextApiRequest, NextApiResponse } from "next"; import { prisma } from "@/lib/api/db"; -import { Session } from "next-auth"; -import { ExtendedLink, NewLink } from "@/types/global"; +import { ExtendedLink } from "@/types/global"; import { existsSync, mkdirSync } from "fs"; import getTitle from "../../getTitle"; import archive from "../../archive"; @@ -9,77 +7,31 @@ import { Link, UsersAndCollections } from "@prisma/client"; import AES from "crypto-js/aes"; import hasAccessToCollection from "@/lib/api/hasAccessToCollection"; -export default async function ( - req: NextApiRequest, - res: NextApiResponse, - session: Session -) { - if (!session?.user?.email) { - return res.status(401).json({ response: "You must be logged in." }); - } - - const email: string = session.user.email; - const link: NewLink = req?.body; +export default async function (link: ExtendedLink, userId: number) { + link.collection.name = link.collection.name.trim(); if (!link.name) { - return res - .status(401) - .json({ response: "Please enter a valid name for the link." }); + return { response: "Please enter a valid name for the link.", status: 401 }; + } else if (!link.collection.name) { + return { response: "Please enter a valid collection name.", status: 401 }; } - if (link.collection.isNew) { - const collectionId = link.collection.id as string; + if (link.collection.ownerId) { + const collectionIsAccessible = await hasAccessToCollection( + userId, + link.collection.id + ); - const findCollection = await prisma.user.findFirst({ - where: { - email, - }, - select: { - collections: { - where: { - name: collectionId, - }, - }, - }, - }); + const memberHasAccess = collectionIsAccessible?.members.some( + (e: UsersAndCollections) => e.userId === userId && e.canCreate + ); - const checkIfCollectionExists = findCollection?.collections[0]; - - if (checkIfCollectionExists) - return res.status(400).json({ response: "Collection already exists." }); - - const newCollection = await prisma.collection.create({ - data: { - owner: { - connect: { - id: session.user.id, - }, - }, - name: collectionId, - }, - }); - - const collectionPath = `data/archives/${newCollection.id}`; - if (!existsSync(collectionPath)) - mkdirSync(collectionPath, { recursive: true }); - - link.collection.id = newCollection.id; + if (!(collectionIsAccessible?.ownerId === userId || memberHasAccess)) + return { response: "Collection is not accessible.", status: 401 }; + } else { + link.collection.ownerId = userId; } - const collectionId = link.collection.id as number; - - const collectionIsAccessible = await hasAccessToCollection( - session.user.id, - collectionId - ); - - const memberHasAccess = collectionIsAccessible?.members.some( - (e: UsersAndCollections) => e.userId === session.user.id && e.canCreate - ); - - if (!(collectionIsAccessible?.ownerId === session.user.id || memberHasAccess)) - return res.status(401).json({ response: "Collection is not accessible." }); - const title = await getTitle(link.url); const newLink: Link = await prisma.link.create({ @@ -87,35 +39,45 @@ export default async function ( name: link.name, url: link.url, collection: { - connect: { - id: collectionId, - }, - }, - tags: { - connectOrCreate: link.tags.map((name) => ({ + connectOrCreate: { where: { - name_collectionId: { - name, - collectionId, + name_ownerId: { + ownerId: link.collection.ownerId, + name: link.collection.name, }, }, create: { - name, - collections: { + name: link.collection.name, + ownerId: userId, + }, + }, + }, + tags: { + connectOrCreate: link.tags.map((tag) => ({ + where: { + name_ownerId: { + name: tag.name, + ownerId: link.collection.ownerId, + }, + }, + create: { + name: tag.name, + owner: { connect: { - id: collectionId, + id: link.collection.ownerId, }, }, }, })), }, title, - starred: false, screenshotPath: "", pdfPath: "", }, }); + console.log(newLink); + const AES_SECRET = process.env.AES_SECRET as string; const screenshotHashedPath = AES.encrypt( @@ -136,7 +98,5 @@ export default async function ( archive(updatedLink.url, updatedLink.collectionId, updatedLink.id); - return res.status(200).json({ - response: updatedLink, - }); + return { response: updatedLink, status: 200 }; } diff --git a/lib/api/controllers/tags/getTags.ts b/lib/api/controllers/tags/getTags.ts index 0fd7bf9..0654eba 100644 --- a/lib/api/controllers/tags/getTags.ts +++ b/lib/api/controllers/tags/getTags.ts @@ -1,12 +1,6 @@ -import type { NextApiRequest, NextApiResponse } from "next"; import { prisma } from "@/lib/api/db"; -import { Session } from "next-auth"; -export default async function ( - req: NextApiRequest, - res: NextApiResponse, - session: Session -) { +export default async function (userId: number) { // tag cleanup await prisma.tag.deleteMany({ where: { @@ -18,15 +12,22 @@ export default async function ( const tags = await prisma.tag.findMany({ where: { - collections: { + ownerId: userId, + owner: { OR: [ { - ownerId: session?.user.id, + id: userId, }, { - members: { + collections: { some: { - userId: session?.user.id, + members: { + some: { + user: { + id: userId, + }, + }, + }, }, }, }, @@ -35,7 +36,5 @@ export default async function ( }, }); - return res.status(200).json({ - response: tags || [], - }); + return { response: tags, status: 200 }; } diff --git a/package.json b/package.json index dd18e92..d70957e 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,10 @@ "eslint-config-next": "13.1.6", "next": "13.1.6", "next-auth": "^4.19.1", - "playwright": "^1.31.2", + "puppeteer": "^19.8.0", + "puppeteer-extra": "^3.3.6", + "puppeteer-extra-plugin-adblocker": "^2.13.6", + "puppeteer-extra-plugin-stealth": "^2.11.2", "react": "18.2.0", "react-dom": "18.2.0", "react-select": "^5.7.0", diff --git a/pages/_app.tsx b/pages/_app.tsx index aff7668..2aa706b 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -3,10 +3,33 @@ import MainLayout from "@/layouts/MainLayout"; import "@/styles/globals.css"; import { SessionProvider } from "next-auth/react"; import type { AppProps } from "next/app"; +import Head from "next/head"; export default function App({ Component, pageProps }: AppProps) { return ( + + Linkwarden + + + + + + diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts index 804774f..c21967b 100644 --- a/pages/api/auth/[...nextauth].ts +++ b/pages/api/auth/[...nextauth].ts @@ -35,6 +35,8 @@ export const authOptions: AuthOptions = { passwordMatches = bcrypt.compareSync(password, findUser.password); } + console.log(passwordMatches); + if (passwordMatches) { return { id: findUser?.id, diff --git a/pages/api/routes/collections/index.ts b/pages/api/routes/collections/index.ts index 2b25189..b2f4b63 100644 --- a/pages/api/routes/collections/index.ts +++ b/pages/api/routes/collections/index.ts @@ -4,21 +4,25 @@ import { authOptions } from "pages/api/auth/[...nextauth]"; import getCollections from "@/lib/api/controllers/collections/getCollections"; import postCollection from "@/lib/api/controllers/collections/postCollection"; -type Data = { - response: object[] | string; -}; - -export default async function ( - req: NextApiRequest, - res: NextApiResponse -) { +export default async function (req: NextApiRequest, res: NextApiResponse) { const session = await getServerSession(req, res, authOptions); if (!session?.user?.email) { return res.status(401).json({ response: "You must be logged in." }); } - if (req.method === "GET") return await getCollections(req, res, session); - - if (req.method === "POST") return await postCollection(req, res, session); + if (req.method === "GET") { + const collections = await getCollections(session.user.id); + return res + .status(collections.status) + .json({ response: collections.response }); + } else if (req.method === "POST") { + const newCollection = await postCollection( + req.body.collectionName.trim(), + session.user.id + ); + return res + .status(newCollection.status) + .json({ response: newCollection.response }); + } } diff --git a/pages/api/routes/links/index.ts b/pages/api/routes/links/index.ts index 7f8cb26..2ef7ae2 100644 --- a/pages/api/routes/links/index.ts +++ b/pages/api/routes/links/index.ts @@ -5,21 +5,25 @@ import getLinks from "@/lib/api/controllers/links/getLinks"; import postLink from "@/lib/api/controllers/links/postLink"; import deleteLink from "@/lib/api/controllers/links/deleteLink"; -type Data = { - response: object[] | string; -}; - -export default async function ( - req: NextApiRequest, - res: NextApiResponse -) { +export default async function (req: NextApiRequest, res: NextApiResponse) { const session = await getServerSession(req, res, authOptions); if (!session?.user?.email) { return res.status(401).json({ response: "You must be logged in." }); } - if (req.method === "GET") return await getLinks(req, res, session); - else if (req.method === "POST") return await postLink(req, res, session); - else if (req.method === "DELETE") return await deleteLink(req, res, session); + if (req.method === "GET") { + const links = await getLinks(session.user.id); + return res.status(links.status).json({ response: links.response }); + } else if (req.method === "POST") { + const newlink = await postLink(req.body, session.user.id); + return res.status(newlink.status).json({ + response: newlink.response, + }); + } else if (req.method === "DELETE") { + const deleted = await deleteLink(req.body, session.user.id); + return res.status(deleted.status).json({ + response: deleted.response, + }); + } } diff --git a/pages/api/routes/tags/index.ts b/pages/api/routes/tags/index.ts index ea0aff5..5bc9b6a 100644 --- a/pages/api/routes/tags/index.ts +++ b/pages/api/routes/tags/index.ts @@ -17,5 +17,8 @@ export default async function ( return res.status(401).json({ response: "You must be logged in." }); } - if (req.method === "GET") return await getTags(req, res, session); + if (req.method === "GET") { + const tags = await getTags(session.user.id); + return res.status(tags.status).json({ response: tags.response }); + } } diff --git a/pages/collections/[id].tsx b/pages/collections/[id].tsx index cf06f26..f1c0cff 100644 --- a/pages/collections/[id].tsx +++ b/pages/collections/[id].tsx @@ -12,10 +12,7 @@ export default function () { return ( // ml-80 -
-

- {linksByCollection.length || 0} Links Found -

+
{linksByCollection.map((e, i) => { return ; })} diff --git a/pages/collections/index.tsx b/pages/collections/index.tsx index 8a9dfe6..b2db463 100644 --- a/pages/collections/index.tsx +++ b/pages/collections/index.tsx @@ -1,20 +1,56 @@ -import { useSession } from "next-auth/react"; import useCollectionStore from "@/store/collections"; - +import { faAdd, faBox, faEllipsis } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import CollectionCard from "@/components/CollectionCard"; +import Dropdown from "@/components/Dropdown"; +import { useState } from "react"; export default function () { const { collections } = useCollectionStore(); - const { data: session, status } = useSession(); - - const user = session?.user; + const [editDropdown, setEditDropdown] = useState(false); return ( // ml-80 -
- {collections.map((e, i) => { - return ; - })} +
+
+
+ +

All Collections

+
+
+
setEditDropdown(!editDropdown)} + id="edit-dropdown" + className="inline-flex rounded-md cursor-pointer hover:bg-white hover:border-sky-500 border-sky-100 border duration-100 p-1" + > + +
+ {editDropdown ? ( + , + }, + ]} + onClickOutside={(e: Event) => { + const target = e.target as HTMLInputElement; + if (target.id !== "edit-dropdown") setEditDropdown(false); + }} + className="absolute top-7 left-0" + /> + ) : null} +
+
+
+ {collections.map((e, i) => { + return ; + })} +
); } diff --git a/pages/links.tsx b/pages/links.tsx new file mode 100644 index 0000000..01fb4e8 --- /dev/null +++ b/pages/links.tsx @@ -0,0 +1,14 @@ +import LinkList from "@/components/LinkList"; +import useLinkStore from "@/store/links"; + +export default function Links() { + const { links } = useLinkStore(); + + return ( +
+ {links.map((e, i) => { + return ; + })} +
+ ); +} diff --git a/pages/login.tsx b/pages/login.tsx index 5f32162..ab3c60d 100644 --- a/pages/login.tsx +++ b/pages/login.tsx @@ -21,6 +21,8 @@ export default function () { password: form.password, }); + console.log(res?.status); + if (res?.ok) { setForm({ email: "", diff --git a/prisma/migrations/20230322214726_renamed_is_favorite_to_starred/migration.sql b/prisma/migrations/20230322214726_renamed_is_favorite_to_starred/migration.sql deleted file mode 100644 index 48f56e6..0000000 --- a/prisma/migrations/20230322214726_renamed_is_favorite_to_starred/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE "Link" RENAME COLUMN "isFavorites" TO "starred"; diff --git a/prisma/migrations/20230312184928_init/migration.sql b/prisma/migrations/20230327225044_init/migration.sql similarity index 88% rename from prisma/migrations/20230312184928_init/migration.sql rename to prisma/migrations/20230327225044_init/migration.sql index 0158c62..b58779b 100644 --- a/prisma/migrations/20230312184928_init/migration.sql +++ b/prisma/migrations/20230327225044_init/migration.sql @@ -37,7 +37,6 @@ CREATE TABLE "Link" ( "url" TEXT NOT NULL, "title" TEXT NOT NULL, "collectionId" INTEGER NOT NULL, - "isFavorites" BOOLEAN NOT NULL, "screenshotPath" TEXT NOT NULL, "pdfPath" TEXT NOT NULL, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, @@ -50,6 +49,7 @@ CREATE TABLE "Tag" ( "id" SERIAL NOT NULL, "name" TEXT NOT NULL, "collectionId" INTEGER NOT NULL, + "ownerId" INTEGER NOT NULL, CONSTRAINT "Tag_pkey" PRIMARY KEY ("id") ); @@ -63,6 +63,12 @@ CREATE TABLE "_LinkToTag" ( -- CreateIndex CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); +-- CreateIndex +CREATE UNIQUE INDEX "Collection_name_ownerId_key" ON "Collection"("name", "ownerId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Tag_name_ownerId_key" ON "Tag"("name", "ownerId"); + -- CreateIndex CREATE UNIQUE INDEX "Tag_name_collectionId_key" ON "Tag"("name", "collectionId"); @@ -87,6 +93,9 @@ ALTER TABLE "Link" ADD CONSTRAINT "Link_collectionId_fkey" FOREIGN KEY ("collect -- AddForeignKey ALTER TABLE "Tag" ADD CONSTRAINT "Tag_collectionId_fkey" FOREIGN KEY ("collectionId") REFERENCES "Collection"("id") ON DELETE RESTRICT ON UPDATE CASCADE; +-- AddForeignKey +ALTER TABLE "Tag" ADD CONSTRAINT "Tag_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + -- AddForeignKey ALTER TABLE "_LinkToTag" ADD CONSTRAINT "_LinkToTag_A_fkey" FOREIGN KEY ("A") REFERENCES "Link"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/20230328031049_init/migration.sql b/prisma/migrations/20230328031049_init/migration.sql new file mode 100644 index 0000000..562ef5b --- /dev/null +++ b/prisma/migrations/20230328031049_init/migration.sql @@ -0,0 +1,2 @@ +-- DropIndex +DROP INDEX "Tag_name_collectionId_key"; diff --git a/prisma/migrations/20230328072406_/migration.sql b/prisma/migrations/20230328072406_/migration.sql new file mode 100644 index 0000000..a70afb8 --- /dev/null +++ b/prisma/migrations/20230328072406_/migration.sql @@ -0,0 +1,11 @@ +/* + Warnings: + + - You are about to drop the column `collectionId` on the `Tag` table. All the data in the column will be lost. + +*/ +-- DropForeignKey +ALTER TABLE "Tag" DROP CONSTRAINT "Tag_collectionId_fkey"; + +-- AlterTable +ALTER TABLE "Tag" DROP COLUMN "collectionId"; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 19c207c..9c5acdf 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -13,6 +13,7 @@ model User { email String @unique password String collections Collection[] + tags Tag[] collectionsJoined UsersAndCollections[] createdAt DateTime @default(now()) } @@ -24,8 +25,9 @@ model Collection { ownerId Int members UsersAndCollections[] links Link[] - tags Tag[] createdAt DateTime @default(now()) + + @@unique([name, ownerId]) } model UsersAndCollections { @@ -50,7 +52,6 @@ model Link { collection Collection @relation(fields: [collectionId], references: [id]) collectionId Int tags Tag[] - starred Boolean screenshotPath String pdfPath String createdAt DateTime @default(now()) @@ -60,8 +61,8 @@ model Tag { id Int @id @default(autoincrement()) name String links Link[] - collections Collection @relation(fields: [collectionId], references: [id]) - collectionId Int + owner User @relation(fields: [ownerId], references: [id]) + ownerId Int - @@unique([name, collectionId]) + @@unique([name, ownerId]) } \ No newline at end of file diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..7e10908b10a42356422b3a79a57bdaee7f3303ab GIT binary patch literal 7020 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 literal 0 HcmV?d00001 diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..7dd41834c45fc4d764dd6d70e98b57ecba0bba3b GIT binary patch literal 23412 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 literal 0 HcmV?d00001 diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..4045c7d1b681fe4a5d669303ae5a48e6b5422bbf GIT binary patch literal 402 zcmV;D0d4+?P)s^p`|}?|;JyzGhQcfi{ieJOOh7}3HUOkK?7#LCYz75xy*@XC3Lh(2 zbK9k_467Uj7=+oG@OuH~>@Womh7FH?FqG(UqiDt(h{%5Kx$>1EK#qf9)q@{!n_*Ff zH4u?CgZzBw({F~xi(eTgnDK#~jSMgh*zGFF-~tSodIN5FfX%=ConeWc0M_(@VZZ@* zL570UpBV&M85wLP*f9KzZVFZ}`~zl-LZBh%-~MJ;?<9!fY`k88C1p_F`u&fAfsGk| w#z1iaI5WKiW+oDVfglURL|A4bK_7-v0IJOY(Okhx8vpB7PrvLx| literal 0 HcmV?d00001 diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..99c38086e25ef2e23957db55fe70bae34aa5aea2 GIT binary patch literal 767 zcmVw+s+N?rJ>;=+}P zt))r@Q9%W}6H|31iMC*E)6}F%JBjB^JIQ2Bnu#-Goo&edzw_VoxJSs-hZX#U{{~<@ zt)ORg7O_;$Q9oLJF7$3|K+q?uIt2$#y-wia*9DcyM!%Tnf{xg zU4~?Ua1?;WkCV8EL}wTBh_p)RCx|*7gku0hBz}y5!~OntTl*x1i?9BJHXR;21j2OBWH2#i~Uka@F(VSd3@+@##*mvKfuLzGk89p z#bdJFC>|M^LYx{~e|vzgqF&{)&4H2c8AKBcINRm}1qin;(Kzy=xJ=@nf-ANFXxTnb zUHi=DdR*S&hafE0yk7h+MSgH8a*e<;fF{n_zD0IpD4xZIuou1C{Uzdh+x4y05`bQu zOD*Vi;WW(dR&tMi`GB(6r& zI1rNXk&@Av?Ug24%>d=Z`EYJDm)<9F{nH$^T9lO9a^tin0OOtO>s+DQm)poA+s12w%LOgX^weCwl0b(Fq|tghJM?(db+6*3ojO;y15 z@>m^+WpTcZYrH{iG}W4n87oXVzz59}1V1bWmmtoCeWvQX8iZ*8BZS{As8fv}82a8` zP0(^5U?)zJ6T{!Krc2G1D$pOoIq@TtQ|GzWucj-oDpv0Q6`$pW#Uvm)xtHL}jDl`j xOl}z$lYh0E@fhdTY@Km6bHZ*jXRi2m{2O0Aq`%Yr#^?Y5002ovPDHLkV1lT&ZHoW^ literal 0 HcmV?d00001 diff --git a/public/favicon.ico b/public/favicon.ico index 718d6fea4835ec2d246af9800eddb7ffb276240c..9844cefdb127351480c0858e56550c4dc6cf56b0 100644 GIT binary patch literal 15406 zcmeHNTZ|M%6m6s5WV6qef#)Bqkd9!5Dl4#z;&6i80Z{koe<=zkc|o zKg!D|k40XFhX^bx68zAJXkdY5cIUA@13SGl-F?01_S9}aXS!#)cSmE+a}u_Q@4@V!p?~{s=aMnr1!6;{LY8TGV+ma z@q@oTaM8AWVm%ob_fcWjV@>-Av}eu*#zk8cTuTR^m+xU8{`PnWoPn$QsOhJvbm)ap z9%1eMeH8XQL0A6xI8>IX_U=BUE%y@}BAB^j?wS-!d_Gkdkz*WWFUgi(mbL=_9@9M|asIEG?hB}1=58-Ee zxjxDj{wb<-MDl;s*c=_Ck;5yfxMy*ub>#4JGOt_=Xb#x94YMe}V-eT;GpdUiV>ZjV zJb(|mft_^$MsfGz08BG{+cL=7Wz8rnQpI2avrh>P#WF8}-vnU@D>c!bqZl844qohueR~%2 zD|%|p!n!#jcTN2)*DUb?;Bc5D@q=wm$gN0ZjSn2yni_9~tFDuQudu?dQStZq{$o4# z9~o8d8+#mJ`OD<(zgF=6YtRorZSSM<0@LL=@+6$1)n4H`lP8(B(_m5sw{4SZg_Be{ z`9A4KS9Mh_pLkEW`D04Ag6jI8l;6Hk)_AP*-B$D4?iCr_oZa6mr#^5vZ@P&}`qw6C=IBL>I53-PA-C(hsMEQ4hfLUGf2mJ-_`vM+Uwx?t3~@89L$bwHaO)Hr+t_@wdpTm1*S1*W~OWYg_7szhg6;>xa#- zyv87^KrZ4@p z%fB}K%lKTCd{Tt3fee0IN^?%P%im`G>;0@-whheL(xDd{IkAbeWk=EMSADiLdgim# z#-LsPARzVu8N_Gyhzyny=JRdmU7p*y&GQoF|62*#34f8nC~&*Wk$D9|u1B z=iI4f8Zt-f`d?%W9_0C6YDKZ>@162jGQ_hb$Y3+?1H49XZiUaRI`vCw@D~~2Yg*V6 zxK}UirQvVxZ1^PXC3*;c$!ycNro~^4Lo-{d6;ILdwtIy8(3W|84)Oro-E5Je-FPWY z{z`^$TjKv(?S0bW{>3eH<@Bdiuly5OS8+&KPU&-LNrF!{q8a=athQ7R2 zY^kvOal9H>i_mXV&oB97Zs0d>8GLJ;>_vH=%HF@RKSi!U&Z&Jqw;TAYad5{=$O(9C zrjeKND4%b-g};))ZA(!$ literal 25931 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 LrJugUA?W`A8`#=m diff --git a/public/icon.png b/public/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ef4dfafd8d828b96ffc90db8dad5c8fbe980cd6a GIT binary patch literal 21476 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 literal 0 HcmV?d00001 diff --git a/public/site.webmanifest b/public/site.webmanifest new file mode 100644 index 0000000..45dc8a2 --- /dev/null +++ b/public/site.webmanifest @@ -0,0 +1 @@ +{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/store/links.ts b/store/links.ts index 9fe9db7..858c2e0 100644 --- a/store/links.ts +++ b/store/links.ts @@ -1,12 +1,12 @@ import { create } from "zustand"; -import { ExtendedLink, NewLink } from "@/types/global"; +import { ExtendedLink } from "@/types/global"; import useTagStore from "./tags"; import useCollectionStore from "./collections"; type LinkStore = { links: ExtendedLink[]; setLinks: () => void; - addLink: (linkName: NewLink) => Promise; + addLink: (linkName: ExtendedLink) => Promise; updateLink: (link: ExtendedLink) => void; removeLink: (link: ExtendedLink) => void; }; @@ -31,6 +31,8 @@ const useLinkStore = create()((set) => ({ const data = await response.json(); + console.log(data); + if (response.ok) set((state) => ({ links: [...state.links, data.response], @@ -43,7 +45,7 @@ const useLinkStore = create()((set) => ({ }, updateLink: (link) => set((state) => ({ - links: state.links.map((c) => (c.id === link.id ? link : c)), + links: state.links.map((e) => (e.id === link.id ? link : e)), })), removeLink: async (link) => { const response = await fetch("/api/routes/links", { diff --git a/types/global.ts b/types/global.ts index 3a3fffc..79decde 100644 --- a/types/global.ts +++ b/types/global.ts @@ -8,9 +8,10 @@ export interface ExtendedLink extends Link { export interface NewLink { name: string; url: string; - tags: string[]; + tags: Tag[]; collection: { - id: string | number; - isNew?: boolean; + id: number | undefined; + name: string | undefined; + ownerId: number | undefined; }; } diff --git a/yarn.lock b/yarn.lock index 0aeaf73..ff456d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -58,6 +58,41 @@ "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" +"@cliqz/adblocker-content@^1.23.8", "@cliqz/adblocker-content@^1.26.3": + version "1.26.3" + resolved "https://registry.yarnpkg.com/@cliqz/adblocker-content/-/adblocker-content-1.26.3.tgz#6f0c78883d6574f0d0ce081a6a79d052c1c89e47" + integrity sha512-Bg6Ex5LNBUnijhlQlkeZqrtKqViqfcTXiXvpXQHMY01pdeZQ70rYBT7HRV5FpQYV3xWkRaQrClanhWz36XWRew== + dependencies: + "@cliqz/adblocker-extended-selectors" "^1.26.3" + +"@cliqz/adblocker-extended-selectors@^1.26.3": + version "1.26.3" + resolved "https://registry.yarnpkg.com/@cliqz/adblocker-extended-selectors/-/adblocker-extended-selectors-1.26.3.tgz#7553158ae78e7a50a263bfc595e521746cceec00" + integrity sha512-wLcP7gkc3YVee/iqkIbFoeweSMbX9aaNUissIlzqDz+8BAci0RXOt4SHj+Ri/TIpTkR5urvhKsmQ8sb1hnJX6Q== + +"@cliqz/adblocker-puppeteer@1.23.8": + version "1.23.8" + resolved "https://registry.yarnpkg.com/@cliqz/adblocker-puppeteer/-/adblocker-puppeteer-1.23.8.tgz#e74636cd200459d1734929e41504a76939504311" + integrity sha512-Ca1/DBqQXsOpKTFVAHX6OpLTSEupXmUkUWHj6iXhLLleC7RPISN5B0b801VDmaGRqoC5zKRxn0vYbIfpgCWVug== + dependencies: + "@cliqz/adblocker" "^1.23.8" + "@cliqz/adblocker-content" "^1.23.8" + tldts-experimental "^5.6.21" + +"@cliqz/adblocker@^1.23.8": + version "1.26.3" + resolved "https://registry.yarnpkg.com/@cliqz/adblocker/-/adblocker-1.26.3.tgz#8ae59ffaf731d26ee515eeb3a9b3d51c28480b90" + integrity sha512-RdXlgNRWEvT+QAVuc81hsitSOObXFkAJiXPL/8PmJ8rFKh0RHfkOpdXl8Xb2GOh2HUbKhy5u9vAhSFMCBKCbCg== + dependencies: + "@cliqz/adblocker-content" "^1.26.3" + "@cliqz/adblocker-extended-selectors" "^1.26.3" + "@remusao/guess-url-type" "^1.1.2" + "@remusao/small" "^1.1.2" + "@remusao/smaz" "^1.7.1" + "@types/chrome" "^0.0.224" + "@types/firefox-webext-browser" "^111.0.0" + tldts-experimental "^5.6.21" + "@emotion/babel-plugin@^11.10.6": version "11.10.6" resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.6.tgz#a68ee4b019d661d6f37dec4b8903255766925ead" @@ -377,6 +412,41 @@ resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-4.9.0.tgz#05a1411964e047c1bc43f777c7a1c69f86a2a26c" integrity sha512-t1pt0Gsp+HcgPJrHFc+d/ZSAaKKWar2G/iakrE07yeKPNavDP3iVKPpfXP22OTCHZUWf7OelwKJxQgKAm5hkgw== +"@remusao/guess-url-type@^1.1.2": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@remusao/guess-url-type/-/guess-url-type-1.2.1.tgz#b3e7c32abdf98d0fb4f93cc67cad580b5fe4ba57" + integrity sha512-rbOqre2jW8STjheOsOaQHLgYBaBZ9Owbdt8NO7WvNZftJlaG3y/K9oOkl8ZUpuFBisIhmBuMEW6c+YrQl5inRA== + +"@remusao/small@^1.1.2": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@remusao/small/-/small-1.2.1.tgz#63bfe4548832289f94ac868a0c305970c9a0e5f9" + integrity sha512-7MjoGt0TJMVw1GPKgWq6SJPws1SLsUXQRa43Umht+nkyw2jnpy3WpiLNqGdwo5rHr5Wp9B2W/Pm5RQp656UJdw== + +"@remusao/smaz-compress@^1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@remusao/smaz-compress/-/smaz-compress-1.9.1.tgz#fc75eaf9bcac2d58bc4c3d518183a7cb9612d275" + integrity sha512-E2f48TwloQu3r6BdLOGF2aczeH7bJ/32oJGqvzT9SKur0cuUnLcZ7ZXP874E2fwmdE+cXzfC7bKzp79cDnmeyw== + dependencies: + "@remusao/trie" "^1.4.1" + +"@remusao/smaz-decompress@^1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@remusao/smaz-decompress/-/smaz-decompress-1.9.1.tgz#8094f997e8fb591a678cda9cf08c209c825eba5b" + integrity sha512-TfjKKprYe3n47od8auhvJ/Ikj9kQTbDTe71ynKlxslrvvUhlIV3VQSuwYuMWMbdz1fIs0H/fxCN1Z8/H3km6/A== + +"@remusao/smaz@^1.7.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@remusao/smaz/-/smaz-1.9.1.tgz#a2b9b045385f81e1615a68d932b7cc8b04c9db8d" + integrity sha512-e6BLuP8oaXCZ9+v46Is4ilAZ/Vq6YLgmBP204Ixgk1qTjXmqvFYG7+AS7v9nsZdGOy96r9DWGFbbDVgMxwu1rA== + dependencies: + "@remusao/smaz-compress" "^1.9.1" + "@remusao/smaz-decompress" "^1.9.1" + +"@remusao/trie@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@remusao/trie/-/trie-1.4.1.tgz#755d09f8a007476334e611f42719b2d581f00720" + integrity sha512-yvwa+aCyYI/UjeD39BnpMypG8N06l86wIDW1/PAc6ihBRnodIfZDwccxQN3n1t74wduzaz74m4ZMHZnB06567Q== + "@rushstack/eslint-patch@^1.1.3": version "1.2.0" resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728" @@ -396,16 +466,58 @@ dependencies: "@types/node" "*" +"@types/chrome@^0.0.224": + version "0.0.224" + resolved "https://registry.yarnpkg.com/@types/chrome/-/chrome-0.0.224.tgz#0138497299eaaf261d61ece62d7d6af3868ce856" + integrity sha512-YkL7q3KDV7OAKgVCBNIfH73rnjNMbIzAYHzTa2DKhSK/2z0Wf/n8yJnK/UoW+lvuYJJR4LtAkG3YvsIZTy7BOA== + dependencies: + "@types/filesystem" "*" + "@types/har-format" "*" + "@types/crypto-js@^4.1.1": version "4.1.1" resolved "https://registry.yarnpkg.com/@types/crypto-js/-/crypto-js-4.1.1.tgz#602859584cecc91894eb23a4892f38cfa927890d" integrity sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA== +"@types/debug@^4.1.0": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" + integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== + dependencies: + "@types/ms" "*" + +"@types/filesystem@*": + version "0.0.32" + resolved "https://registry.yarnpkg.com/@types/filesystem/-/filesystem-0.0.32.tgz#307df7cc084a2293c3c1a31151b178063e0a8edf" + integrity sha512-Yuf4jR5YYMR2DVgwuCiP11s0xuVRyPKmz8vo6HBY3CGdeMj8af93CFZX+T82+VD1+UqHOxTq31lO7MI7lepBtQ== + dependencies: + "@types/filewriter" "*" + +"@types/filewriter@*": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/filewriter/-/filewriter-0.0.29.tgz#a48795ecadf957f6c0d10e0c34af86c098fa5bee" + integrity sha512-BsPXH/irW0ht0Ji6iw/jJaK8Lj3FJemon2gvEqHKpCdDCeemHa+rI3WBGq5z7cDMZgoLjY40oninGxqk+8NzNQ== + +"@types/firefox-webext-browser@^111.0.0": + version "111.0.0" + resolved "https://registry.yarnpkg.com/@types/firefox-webext-browser/-/firefox-webext-browser-111.0.0.tgz#16311d8da94e21a715d1688ba8547069eb89cf5a" + integrity sha512-KboW0ughUYzuYAvzWGJsiSMmH9AgJDvnstjsNrXMgf6cpJ5g1eBGzkqpjPzVqkOyTH/mFl7gd15+XyaVQhKywA== + +"@types/har-format@*": + version "1.2.10" + resolved "https://registry.yarnpkg.com/@types/har-format/-/har-format-1.2.10.tgz#7b4e1e0ada4d17684ac3b05d601a4871cfab11fc" + integrity sha512-o0J30wqycjF5miWDKYKKzzOU1ZTLuA42HZ4HE7/zqTOc/jTLdQ5NhYWvsRQo45Nfi1KHoRdNhteSI4BAxTF1Pg== + "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/ms@*": + version "0.7.31" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" + integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== + "@types/node@*": version "18.11.19" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.19.tgz#35e26df9ec441ab99d73e99e9aca82935eea216d" @@ -454,6 +566,13 @@ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== +"@types/yauzl@^2.9.1": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.0.tgz#b3248295276cf8c6f153ebe6a9aba0c988cb2599" + integrity sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw== + dependencies: + "@types/node" "*" + "@typescript-eslint/parser@^5.42.0": version "5.49.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.49.0.tgz#d699734b2f20e16351e117417d34a2bc9d7c4b90" @@ -606,6 +725,11 @@ aria-query@^5.1.3: dependencies: deep-equal "^2.0.5" +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== + array-includes@^3.1.5, array-includes@^3.1.6: version "3.1.6" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" @@ -701,6 +825,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + bcrypt@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/bcrypt/-/bcrypt-5.1.0.tgz#bbb27665dbc400480a524d8991ac7434e8529e17" @@ -714,6 +843,15 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -739,6 +877,19 @@ browserslist@^4.21.4: node-releases "^2.0.6" update-browserslist-db "^1.0.9" +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + +buffer@^5.2.1, buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -794,16 +945,39 @@ chokidar@^3.5.3: optionalDependencies: fsevents "~2.3.2" +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + chownr@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== +chromium-bidi@0.4.5: + version "0.4.5" + resolved "https://registry.yarnpkg.com/chromium-bidi/-/chromium-bidi-0.4.5.tgz#a352e755536dde609bd2c77e4b1f0906bff8784e" + integrity sha512-rkav9YzRfAshSTG3wNXF7P7yNiI29QAo1xBXElPoCoSQR5n20q3cOyVhDv6S7+GlF/CJ/emUxlQiR0xOPurkGg== + dependencies: + mitt "3.0.0" + client-only@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== +clone-deep@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-0.2.4.tgz#4e73dd09e9fb971cc38670c5dced9c1896481cc6" + integrity sha512-we+NuQo2DHhSl+DP6jlUiAhyAjBQrYnpOk15rN6c6JSPScjiCLh8IbSU+VTcph6YS3o7mASE8a0+gbZ7ChLpgg== + dependencies: + for-own "^0.1.3" + is-plain-object "^2.0.1" + kind-of "^3.0.2" + lazy-cache "^1.0.3" + shallow-clone "^0.1.2" + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -853,6 +1027,16 @@ cookie@^0.5.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cosmiconfig@8.1.3: + version "8.1.3" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.1.3.tgz#0e614a118fcc2d9e5afc2f87d53cd09931015689" + integrity sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw== + dependencies: + import-fresh "^3.2.1" + js-yaml "^4.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + cosmiconfig@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" @@ -864,6 +1048,13 @@ cosmiconfig@^7.0.0: path-type "^4.0.0" yaml "^1.10.0" +cross-fetch@3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" + integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== + dependencies: + node-fetch "2.6.7" + cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -893,7 +1084,7 @@ damerau-levenshtein@^1.0.8: resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== -debug@4, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: +debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -935,6 +1126,11 @@ deep-is@^0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + define-lazy-prop@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" @@ -972,6 +1168,11 @@ detective@^5.2.1: defined "^1.0.0" minimist "^1.2.6" +devtools-protocol@0.0.1107588: + version "0.0.1107588" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1107588.tgz#f8cac707840b97cc30b029359341bcbbb0ad8ffa" + integrity sha512-yIR+pG9x65Xko7bErCUSQaDLrO/P1p3JUzEk7JCU4DowPcGHkTGUGQapcfcLc4qj0UaALwZ+cr0riFgiqpixcg== + didyoumean@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" @@ -1026,6 +1227,13 @@ emoji-regex@^9.2.2: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== +end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + enhanced-resolve@^5.10.0: version "5.12.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz#300e1c90228f5b570c4d35babf263f6da7155634" @@ -1351,6 +1559,17 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +extract-zip@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" + integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== + dependencies: + debug "^4.1.1" + get-stream "^5.1.0" + yauzl "^2.10.0" + optionalDependencies: + "@types/yauzl" "^2.9.1" + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -1384,6 +1603,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== + dependencies: + pend "~1.2.0" + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -1431,11 +1657,42 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" +for-in@^0.1.3: + version "0.1.8" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1" + integrity sha512-F0to7vbBSHP8E3l6dCjxNOLuSFAACIxFy3UehTUlG7svlXi37HHsDkyVcHo0Pq8QwrE+pXvWSVX3ZT1T9wAZ9g== + +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== + +for-own@^0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha512-SKmowqGTJoPzLO1T0BBJpkfp3EMacCMOuH40hOUbrbzElVktk4DioXVM99QkLCyKoiuOmyjgcWMpVz2xjE7LZw== + dependencies: + for-in "^1.0.1" + fraction.js@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-extra@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -1497,6 +1754,13 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: has "^1.0.3" has-symbols "^1.0.3" +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + get-symbol-description@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" @@ -1602,6 +1866,11 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" +graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + graceful-fs@^4.2.4: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" @@ -1670,7 +1939,7 @@ hoist-non-react-statics@^3.3.1: dependencies: react-is "^16.7.0" -https-proxy-agent@^5.0.0: +https-proxy-agent@5.0.1, https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== @@ -1678,6 +1947,11 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore@^5.2.0: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" @@ -1704,7 +1978,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.3: +inherits@2, inherits@^2.0.3, inherits@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -1762,6 +2036,11 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-buffer@^1.0.2, is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" @@ -1786,6 +2065,11 @@ is-docker@^2.0.0, is-docker@^2.1.1: resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== +is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -1830,6 +2114,13 @@ is-path-inside@^3.0.3: resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== +is-plain-object@^2.0.1: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -1912,6 +2203,11 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + jose@^4.10.0, jose@^4.9.3: version "4.11.2" resolved "https://registry.yarnpkg.com/jose/-/jose-4.11.2.tgz#d9699307c02e18ff56825843ba90e2fae9f09e23" @@ -1956,6 +2252,15 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" @@ -1964,6 +2269,20 @@ json5@^1.0.1: array-includes "^3.1.5" object.assign "^4.1.3" +kind-of@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-2.0.1.tgz#018ec7a4ce7e3a86cb9141be519d24c8faa981b5" + integrity sha512-0u8i1NZ/mg0b+W3MGGw5I7+6Eib2nx72S/QvXa0hYjEkjTknYmEYQJwGu3mLC0BrhtJjtQafTkyRUQ75Kx0LVg== + dependencies: + is-buffer "^1.0.2" + +kind-of@^3.0.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== + dependencies: + is-buffer "^1.1.5" + language-subtag-registry@~0.3.2: version "0.3.22" resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" @@ -1976,6 +2295,16 @@ language-tags@=1.0.5: dependencies: language-subtag-registry "~0.3.2" +lazy-cache@^0.2.3: + version "0.2.7" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65" + integrity sha512-gkX52wvU/R8DVMMt78ATVPFMJqfW8FPz1GZ1sVHBVQHmu/WvhIWE4cE1GBzhJNFicDeYhnwp6Rl35BcAIM3YOQ== + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + integrity sha512-RE2g0b5VGZsOCFOCgP7omTRYFqydmZkBwl5oNnQ1lDYC57uyO9KqNnNVxT7COSHTxrRCWVcAVOcbjk+tvh/rgQ== + levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -2032,6 +2361,15 @@ memoize-one@^6.0.0: resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045" integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw== +merge-deep@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/merge-deep/-/merge-deep-3.0.3.tgz#1a2b2ae926da8b2ae93a0ac15d90cd1922766003" + integrity sha512-qtmzAS6t6grwEkNrunqTBdn0qKwFgNWvlxUbAV8es9M7Ot1EbyApytCnvE0jALPa46ZpKDUo527kKiaWplmlFA== + dependencies: + arr-union "^3.1.0" + clone-deep "^0.2.4" + kind-of "^3.0.2" + merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" @@ -2077,6 +2415,24 @@ minizlib@^2.1.1: minipass "^3.0.0" yallist "^4.0.0" +mitt@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.0.tgz#69ef9bd5c80ff6f57473e8d89326d01c414be0bd" + integrity sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ== + +mixin-object@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mixin-object/-/mixin-object-2.0.1.tgz#4fb949441dab182540f1fe035ba60e1947a5e57e" + integrity sha512-ALGF1Jt9ouehcaXaHhn6t1yGWRqGaHkPFndtFVHfZXOvkIZ/yoGaSi0AHVTafb3ZBGg4dr/bDwnaEKqCXzchMA== + dependencies: + for-in "^0.1.3" + is-extendable "^0.1.1" + +mkdirp-classic@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + mkdirp@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" @@ -2147,7 +2503,14 @@ node-addon-api@^5.0.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA== -node-fetch@^2.6.7: +node-fetch@2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + +node-fetch@^2.6.0, node-fetch@^2.6.7: version "2.6.9" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== @@ -2274,7 +2637,7 @@ oidc-token-hash@^5.0.1: resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-5.0.1.tgz#ae6beec3ec20f0fd885e5400d175191d6e2f10c6" integrity sha512-EvoOtz6FIEBzE+9q253HsLCVRiK/0doEJ2HCvvqMQb3dHZrP3WlJKYtJ55CRTw4jmYomzH4wkPuCj/I3ZvpKxQ== -once@^1.3.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -2368,6 +2731,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -2383,18 +2751,6 @@ pify@^2.3.0: resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== -playwright-core@1.31.2: - version "1.31.2" - resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.31.2.tgz#debf4b215d14cb619adb7e511c164d068075b2ed" - integrity sha512-a1dFgCNQw4vCsG7bnojZjDnPewZcw7tZUNFN0ZkcLYKj+mPmXvg4MpaaKZ5SgqPsOmqIf2YsVRkgqiRDxD+fDQ== - -playwright@^1.31.2: - version "1.31.2" - resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.31.2.tgz#4252280586c596746122cd1fdf9f8ff6a63fa852" - integrity sha512-jpC47n2PKQNtzB7clmBuWh6ftBRS/Bt5EGLigJ9k2QAKcNeYXZkEaDH5gmvb6+AbcE0DO6GnXdbl9ogG6Eh+og== - dependencies: - playwright-core "1.31.2" - postcss-import@^14.1.0: version "14.1.0" resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-14.1.0.tgz#a7333ffe32f0b8795303ee9e40215dac922781f0" @@ -2486,6 +2842,11 @@ prisma@^4.9.0: dependencies: "@prisma/engines" "4.9.0" +progress@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" @@ -2495,11 +2856,108 @@ prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.8.1: object-assign "^4.1.1" react-is "^16.13.1" +proxy-from-env@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + punycode@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== +puppeteer-core@19.8.0: + version "19.8.0" + resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-19.8.0.tgz#0152f652a64274f93f681b52ed03baf7de7905dd" + integrity sha512-5gBkLR9nae7chWDhI3mpj5QA+hPmjEOW29qw5ap5g51Uo5Lxe5Yip1uyQwZSjg5Wn/eyE9grh2Lyx3m8rPK90A== + dependencies: + chromium-bidi "0.4.5" + cross-fetch "3.1.5" + debug "4.3.4" + devtools-protocol "0.0.1107588" + extract-zip "2.0.1" + https-proxy-agent "5.0.1" + proxy-from-env "1.1.0" + tar-fs "2.1.1" + unbzip2-stream "1.4.3" + ws "8.13.0" + +puppeteer-extra-plugin-adblocker@^2.13.6: + version "2.13.6" + resolved "https://registry.yarnpkg.com/puppeteer-extra-plugin-adblocker/-/puppeteer-extra-plugin-adblocker-2.13.6.tgz#99828243579b59ed81e8b1da23d16a3a0dbae557" + integrity sha512-AftgnUZ1rg2RPe9RpX6rkYAxEohwp3iFeGIyjsAuTaIiw4VLZqOb1LSY8/S60vAxpeat60fbCajxoUetmLy4Dw== + dependencies: + "@cliqz/adblocker-puppeteer" "1.23.8" + debug "^4.1.1" + node-fetch "^2.6.0" + puppeteer-extra-plugin "^3.2.3" + +puppeteer-extra-plugin-stealth@^2.11.2: + version "2.11.2" + resolved "https://registry.yarnpkg.com/puppeteer-extra-plugin-stealth/-/puppeteer-extra-plugin-stealth-2.11.2.tgz#bd3f5a1781cac8a98c983d148086585a84fcc8f1" + integrity sha512-bUemM5XmTj9i2ZerBzsk2AN5is0wHMNE6K0hXBzBXOzP5m5G3Wl0RHhiqKeHToe/uIH8AoZiGhc1tCkLZQPKTQ== + dependencies: + debug "^4.1.1" + puppeteer-extra-plugin "^3.2.3" + puppeteer-extra-plugin-user-preferences "^2.4.1" + +puppeteer-extra-plugin-user-data-dir@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/puppeteer-extra-plugin-user-data-dir/-/puppeteer-extra-plugin-user-data-dir-2.4.1.tgz#4ea9d56d20455672a54fe086309a102a5126411c" + integrity sha512-kH1GnCcqEDoBXO7epAse4TBPJh9tEpVEK/vkedKfjOVOhZAvLkHGc9swMs5ChrJbRnf8Hdpug6TJlEuimXNQ+g== + dependencies: + debug "^4.1.1" + fs-extra "^10.0.0" + puppeteer-extra-plugin "^3.2.3" + rimraf "^3.0.2" + +puppeteer-extra-plugin-user-preferences@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/puppeteer-extra-plugin-user-preferences/-/puppeteer-extra-plugin-user-preferences-2.4.1.tgz#db8ec63c04a6a10a8f8997e15fdffdf13272161d" + integrity sha512-i1oAZxRbc1bk8MZufKCruCEC3CCafO9RKMkkodZltI4OqibLFXF3tj6HZ4LZ9C5vCXZjYcDWazgtY69mnmrQ9A== + dependencies: + debug "^4.1.1" + deepmerge "^4.2.2" + puppeteer-extra-plugin "^3.2.3" + puppeteer-extra-plugin-user-data-dir "^2.4.1" + +puppeteer-extra-plugin@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/puppeteer-extra-plugin/-/puppeteer-extra-plugin-3.2.3.tgz#50c9f0749c005bbc7b8b208bcd00a9d46a15b585" + integrity sha512-6RNy0e6pH8vaS3akPIKGg28xcryKscczt4wIl0ePciZENGE2yoaQJNd17UiEbdmh5/6WW6dPcfRWT9lxBwCi2Q== + dependencies: + "@types/debug" "^4.1.0" + debug "^4.1.1" + merge-deep "^3.0.1" + +puppeteer-extra@^3.3.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/puppeteer-extra/-/puppeteer-extra-3.3.6.tgz#fc16ff396aae52664842da9a557ea8fa51eaa8b7" + integrity sha512-rsLBE/6mMxAjlLd06LuGacrukP2bqbzKCLzV1vrhHFavqQE/taQ2UXv3H5P0Ls7nsrASa+6x3bDbXHpqMwq+7A== + dependencies: + "@types/debug" "^4.1.0" + debug "^4.1.1" + deepmerge "^4.2.2" + +puppeteer@^19.8.0: + version "19.8.0" + resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-19.8.0.tgz#2d2225fb24ba6813cd31304d41c6b8340c9f3582" + integrity sha512-MpQClmttCUxv4bVokX/YSXLCU12CUApuRf0rIJyGknYcIrDQNkLUx1N7hNt88Ya4lq9VDsdiDEJ3bcPijqJYPQ== + dependencies: + cosmiconfig "8.1.3" + https-proxy-agent "5.0.1" + progress "2.0.3" + proxy-from-env "1.1.0" + puppeteer-core "19.8.0" + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -2562,6 +3020,15 @@ read-cache@^1.0.0: dependencies: pify "^2.3.0" +readable-stream@^3.1.1, readable-stream@^3.4.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" @@ -2677,6 +3144,16 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== +shallow-clone@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-0.1.2.tgz#5909e874ba77106d73ac414cfec1ffca87d97060" + integrity sha512-J1zdXCky5GmNnuauESROVu31MQSnLoYvlyEn6j2Ztk6Q5EHFIhxkMhYcv6vuDzl2XEzoRr856QwzMgWM/TmZgw== + dependencies: + is-extendable "^0.1.1" + kind-of "^2.0.1" + lazy-cache "^0.2.3" + mixin-object "^2.0.1" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -2868,6 +3345,27 @@ tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +tar-fs@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + tar@^6.1.11: version "6.1.13" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.13.tgz#46e22529000f612180601a6fe0680e7da508847b" @@ -2885,6 +3383,11 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== +through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + tiny-glob@^0.2.9: version "0.2.9" resolved "https://registry.yarnpkg.com/tiny-glob/-/tiny-glob-0.2.9.tgz#2212d441ac17928033b110f8b3640683129d31e2" @@ -2893,6 +3396,18 @@ tiny-glob@^0.2.9: globalyzer "0.1.0" globrex "^0.1.2" +tldts-core@^5.7.112: + version "5.7.112" + resolved "https://registry.yarnpkg.com/tldts-core/-/tldts-core-5.7.112.tgz#168459aa79495f5d46407a685a7a9f0cdc9a272b" + integrity sha512-mutrEUgG2sp0e/MIAnv9TbSLR0IPbvmAImpzqul5O/HJ2XM1/I1sajchQ/fbj0fPdA31IiuWde8EUhfwyldY1Q== + +tldts-experimental@^5.6.21: + version "5.7.112" + resolved "https://registry.yarnpkg.com/tldts-experimental/-/tldts-experimental-5.7.112.tgz#6a44be12811161e7daf2e89950563b8e7da94ed1" + integrity sha512-Nq5qWN4OiLziAOOOEoSME7cZI4Hz8Srt+9q6cl8mZ5EAhCfmeE6l7K5XjuIKN+pySuGUvthE5aPiD185YU1/lg== + dependencies: + tldts-core "^5.7.112" + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -2973,6 +3488,19 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +unbzip2-stream@1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" + integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== + dependencies: + buffer "^5.2.1" + through "^2.3.8" + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + update-browserslist-db@^1.0.9: version "1.0.10" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" @@ -3078,6 +3606,11 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== +ws@8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== + xtend@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" @@ -3093,6 +3626,14 @@ yaml@^1.10.0, yaml@^1.10.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +yauzl@^2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"