diff --git a/README.md b/README.md
index 71d769d..99e8026 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-// LOGO OR BANNER GOES HERE
+
## Status
### Project halted at the moment.
@@ -13,7 +13,7 @@ I'm currently working on a workaround for this, but it's not a priority for me a
~~You can check the demo [here](https://drive.mbaharip.com).~~
## What is this?
-gudora-index is an indexer for Google Drive, it's a simple project that I made to index my files in Google Drive.
+`next-gdrive-index` is an indexer for Google Drive, it's a simple project that I made to index my files in Google Drive.
It's aim to simplify the process of sharing files using Google Drive, and also implements some features that I think is useful for sharing files.
This project are **HEAVILY INSPIRED** by [onedrive-vercel-index](https://github.com/spencerwooo/onedrive-vercel-index) by SpencerWooo.
@@ -46,7 +46,7 @@ I know there are a lot of people selling cheap edu account for Google Drive and
## TODO
- [ ] Aim for max 1.5s response time for every API routes
- Fetch all routes - 600~900ms
- - Fetch file or folder -
+ - Fetch file or folder - 700~1400ms
- [x] Navigate through folders
- [ ] File preview
- [x] Audio
diff --git a/package.json b/package.json
index d3d3a15..2fee51f 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
"@types/react": "18.0.35",
"@types/react-dom": "18.0.11",
"@upstash/redis": "^1.20.4",
+ "@vercel/og": "^0.5.4",
"autoprefixer": "10.4.14",
"axios": "^1.3.5",
"cors": "^2.8.5",
diff --git a/public/favicon.png b/public/favicon.png
new file mode 100644
index 0000000..a9c4021
Binary files /dev/null and b/public/favicon.png differ
diff --git a/public/favicon.svg b/public/favicon.svg
new file mode 100644
index 0000000..5c31a8a
--- /dev/null
+++ b/public/favicon.svg
@@ -0,0 +1,713 @@
+
+
+
diff --git a/public/fonts/Exo2-Bold.ttf b/public/fonts/Exo2-Bold.ttf
new file mode 100644
index 0000000..8404285
Binary files /dev/null and b/public/fonts/Exo2-Bold.ttf differ
diff --git a/public/fonts/Exo2-Regular.ttf b/public/fonts/Exo2-Regular.ttf
new file mode 100644
index 0000000..63bc4bb
Binary files /dev/null and b/public/fonts/Exo2-Regular.ttf differ
diff --git a/public/logo.svg b/public/logo.svg
new file mode 100644
index 0000000..6885c17
--- /dev/null
+++ b/public/logo.svg
@@ -0,0 +1,700 @@
+
+
+
diff --git a/public/og.png b/public/og.png
new file mode 100644
index 0000000..ad92661
Binary files /dev/null and b/public/og.png differ
diff --git a/src/config/site.config.js b/src/config/site.config.js
index 130aff1..b900ae8 100644
--- a/src/config/site.config.js
+++ b/src/config/site.config.js
@@ -3,13 +3,13 @@ import { BsDiscord, BsGithub, BsPaypal } from "react-icons/bs";
const config = {
/* Site MetaData */
// The name of the site
- siteName: "My Drive Linker",
+ siteName: "mbahArip Stash",
// The description of the site
// Used in meta tags and document head
- siteDescription: "My Drive Linker",
+ siteDescription: "Personal Stash of mbahArip, a place to store my files.",
// Fav icon of the site
// Also used as the logo of the site on the navbar
- siteIcon: "/favicon.ico",
+ siteIcon: "/favicon.svg",
// Navbar menu links
navbarLinks: [
{
@@ -38,8 +38,8 @@ const config = {
],
// Footer text
// It will be rendered as
- // {year} {footerText} - Powered by guDora-index {version} ❤️
- footerText: "gDrive Linker",
+ // {year} {footerText} - Powered by next-gdrive-index ❤️
+ footerText: "mbahArip Stash",
/* Experimental: Render Banner */
banner: {
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index dd00d37..b4275a2 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -51,9 +51,10 @@ export default function App({ Component, pageProps }: AppProps) {
type: "website",
title: config.siteName,
description: config.siteDescription,
+ url: process.env.NEXT_PUBLIC_DOMAIN,
images: [
{
- url: `${process.env.NEXT_PUBLIC_DOMAIN}/og-image.png`,
+ url: `${process.env.NEXT_PUBLIC_DOMAIN}/api/og`,
width: 1200,
height: 630,
alt: config.siteName,
diff --git a/src/pages/api/files/[id]/index.ts b/src/pages/api/files/[id]/index.ts
index 79c6259..830208c 100644
--- a/src/pages/api/files/[id]/index.ts
+++ b/src/pages/api/files/[id]/index.ts
@@ -16,7 +16,7 @@ export default initMiddleware(async function handler(
const _start = Date.now();
try {
- const { id, pageToken, download } = request.query;
+ const { id, pageToken, download, thumbnail, banner } = request.query;
const [name, partialId] = (id as string).split(":");
@@ -49,6 +49,9 @@ export default initMiddleware(async function handler(
response.setHeader("Cache-Control", apiConfig.cache);
if (file.mimeType !== "application/vnd.google-apps.folder") {
+ if (thumbnail === "1") {
+ return response.status(301).redirect(file.thumbnailLink as string);
+ }
if (download === "1") {
// Check size
if (Number(file.size as string) > apiConfig.maxResponseSize) {
@@ -109,6 +112,38 @@ export default initMiddleware(async function handler(
const isReadmeExists = !!fetchFolderContents.data.files?.find(
(file) => file.name === ".readme.md",
);
+ const isBannerExists = !!fetchFolderContents.data.files?.find((file) =>
+ file.name?.startsWith(".banner"),
+ );
+
+ if (banner === "1") {
+ if (!isBannerExists) {
+ throw new ExtendedError("Banner not found.", 404, "notFound");
+ }
+ const bannerFile = fetchFolderContents.data.files?.find((file) =>
+ file.name?.startsWith(".banner"),
+ );
+ const bannerFileStream = await driveClient.files.get(
+ {
+ fileId: bannerFile?.id as string,
+ alt: "media",
+ },
+ { responseType: "stream" },
+ );
+ response.setHeader(
+ "Content-Type",
+ bannerFile?.mimeType || "application/octet-stream",
+ );
+ response.setHeader(
+ "Content-Disposition",
+ `attachment; filename=${encodeURIComponent(
+ bannerFile?.name as string,
+ )}`,
+ );
+ response.setHeader("Content-Length", bannerFile?.size as string);
+ return response.status(200).send(bannerFileStream.data);
+ }
+
// Get only folder, since we order the folder to be first, we can just get all the folder first
const folderList =
fetchFolderContents.data.files
@@ -126,7 +161,10 @@ export default initMiddleware(async function handler(
?.filter(
(item) =>
!item.mimeType?.startsWith("application/vnd.google-apps") &&
- !hiddenFiles.includes(item.name as string),
+ // !hiddenFiles.includes(item.name as string),
+ !hiddenFiles.some((hiddenFile) =>
+ item.name?.startsWith(hiddenFile),
+ ),
)
.map((item) => ({
...item,
diff --git a/src/pages/api/files/index.ts b/src/pages/api/files/index.ts
index d97eeeb..0e39c00 100644
--- a/src/pages/api/files/index.ts
+++ b/src/pages/api/files/index.ts
@@ -47,7 +47,10 @@ export default initMiddleware(async function handler(
?.filter(
(item) =>
!item.mimeType?.startsWith("application/vnd.google-apps") &&
- !hiddenFiles.includes(item.name as string),
+ // !hiddenFiles.includes(item.name as string),
+ !hiddenFiles.some((hiddenFile) =>
+ item.name?.startsWith(hiddenFile),
+ ),
)
.map((item) => ({
...item,
diff --git a/src/pages/api/og-folder.tsx b/src/pages/api/og-folder.tsx
new file mode 100644
index 0000000..cbccf29
--- /dev/null
+++ b/src/pages/api/og-folder.tsx
@@ -0,0 +1,181 @@
+import { ImageResponse } from "@vercel/og";
+import siteConfig from "config/site.config";
+import { NextRequest } from "next/server";
+
+export const config = {
+ runtime: "edge",
+};
+
+const fontBold = fetch(
+ new URL("../../../public/fonts/Exo2-Bold.ttf", import.meta.url),
+).then((res) => res.arrayBuffer());
+const fontRegular = fetch(
+ new URL("../../../public/fonts/Exo2-Regular.ttf", import.meta.url),
+).then((res) => res.arrayBuffer());
+
+export default async function handler(request: NextRequest) {
+ try {
+ const exoFont = await fontRegular;
+ const exoFontBold = await fontBold;
+
+ const { searchParams } = new URL(request.url);
+
+ const siteName = searchParams.get("siteName") || siteConfig.siteName;
+ const fileId = searchParams.get("fileId") || null;
+ const fileName =
+ searchParams.get("fileName") || fileId?.split(":")[0] || null;
+
+ console.log("Creating og image for", fileName);
+
+ let fileImage;
+ if (fileId) {
+ await fetch(
+ `${process.env.NEXT_PUBLIC_DOMAIN}/api/files/${fileId}?banner=1`,
+ )
+ .then((res) => {
+ if (res.headers.get("content-type")?.startsWith("image")) {
+ return { success: true };
+ }
+ return res.json();
+ })
+ .then((data) => {
+ if (!data.success) {
+ throw new Error("File not found");
+ }
+ fileImage = `${process.env.NEXT_PUBLIC_DOMAIN}/api/files/${fileId}?banner=1`;
+ })
+ .catch((err) => {
+ throw new Error(err);
+ });
+ } else {
+ throw new Error("Default image");
+ }
+
+ return new ImageResponse(
+ (
+
+
+

+
+
+
+

+
+
+ {siteName}
+
+
+ {fileName}
+
+
+
+

+
+
+
+
Powered by
+

+
+ next-gdrive-index
+
+
+
+ ),
+ {
+ width: 1200,
+ height: 630,
+ fonts: [
+ {
+ name: "Exo2",
+ data: exoFont,
+ weight: 400,
+ style: "normal",
+ },
+ {
+ name: "Exo2",
+ data: exoFontBold,
+ weight: 700,
+ style: "normal",
+ },
+ ],
+ },
+ );
+ } catch (e) {
+ return new ImageResponse(
+ (
+
+

+
+ ),
+ {
+ width: 1200,
+ height: 630,
+ },
+ );
+ }
+}
diff --git a/src/pages/api/og.tsx b/src/pages/api/og.tsx
new file mode 100644
index 0000000..cbcdc5f
--- /dev/null
+++ b/src/pages/api/og.tsx
@@ -0,0 +1,189 @@
+import { ImageResponse } from "@vercel/og";
+import siteConfig from "config/site.config";
+import { NextRequest } from "next/server";
+
+export const config = {
+ runtime: "edge",
+};
+
+const fontBold = fetch(
+ new URL("../../../public/fonts/Exo2-Bold.ttf", import.meta.url),
+).then((res) => res.arrayBuffer());
+const fontRegular = fetch(
+ new URL("../../../public/fonts/Exo2-Regular.ttf", import.meta.url),
+).then((res) => res.arrayBuffer());
+
+export default async function handler(request: NextRequest) {
+ try {
+ const exoFont = await fontRegular;
+ const exoFontBold = await fontBold;
+
+ const { searchParams } = new URL(request.url);
+
+ const siteName = searchParams.get("siteName") || siteConfig.siteName;
+ const fileId = searchParams.get("fileId") || null;
+ const fileName =
+ searchParams.get("fileName") || fileId?.split(":")[0] || null;
+ const fileExt = fileName?.split(".").pop() || null;
+
+ const isImage = ["jpg", "jpeg", "png", "gif", "webp"].includes(
+ fileExt || "",
+ );
+
+ console.log("Creating og image for", fileName);
+ console.log(fileId, isImage);
+
+ let fileImage;
+ if (fileId && isImage) {
+ fileImage = `${process.env.NEXT_PUBLIC_DOMAIN}/api/files/${fileId}?download=1`;
+ } else if (fileId && !isImage) {
+ await fetch(
+ `${process.env.NEXT_PUBLIC_DOMAIN}/api/files/${fileId}?thumbnail=1`,
+ )
+ .then((res) => {
+ if (res.headers.get("content-type")?.startsWith("image")) {
+ return { success: true };
+ }
+ return res.json();
+ })
+ .then((data) => {
+ if (!data.success) {
+ throw new Error("File not found");
+ }
+ })
+ .catch((err) => {
+ throw new Error(err);
+ });
+ fileImage = `${process.env.NEXT_PUBLIC_DOMAIN}/api/files/${fileId}?thumbnail=1`;
+ } else {
+ throw new Error("Default image");
+ }
+
+ return new ImageResponse(
+ (
+
+
+

+
+
+
+

+
+
+ {siteName}
+
+
+ {fileName}
+
+
+
+

+
+
+
+
Powered by
+

+
+ next-gdrive-index
+
+
+
+ ),
+ {
+ width: 1200,
+ height: 630,
+ fonts: [
+ {
+ name: "Exo2",
+ data: exoFont,
+ weight: 400,
+ style: "normal",
+ },
+ {
+ name: "Exo2",
+ data: exoFontBold,
+ weight: 700,
+ style: "normal",
+ },
+ ],
+ },
+ );
+ } catch (e) {
+ return new ImageResponse(
+ (
+
+

+
+ ),
+ {
+ width: 1200,
+ height: 630,
+ },
+ );
+ }
+}
diff --git a/src/pages/api/search.ts b/src/pages/api/search.ts
index cd20cb7..8b81aa3 100644
--- a/src/pages/api/search.ts
+++ b/src/pages/api/search.ts
@@ -39,7 +39,10 @@ export default async function handler(
searchFile.data.files
?.filter(
(item) =>
- !hiddenFiles.includes(item.name as string) &&
+ // !hiddenFiles.includes(item.name as string),
+ !hiddenFiles.some((hiddenFile) =>
+ item.name?.startsWith(hiddenFile),
+ ) &&
(!item.mimeType?.startsWith("application/vnd.google-apps") ||
item.mimeType === "application/vnd.google-apps.folder"),
)
diff --git a/src/utils/driveHelper.ts b/src/utils/driveHelper.ts
index d41aa59..37e977b 100644
--- a/src/utils/driveHelper.ts
+++ b/src/utils/driveHelper.ts
@@ -1,4 +1,4 @@
-export const hiddenFiles = [".password", ".readme.md"];
+export const hiddenFiles = [".password", ".readme.md", ".banner"];
export class ExtendedError extends Error {
code?: number;
diff --git a/tsconfig.json b/tsconfig.json
index 399192c..f831cee 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -25,6 +25,6 @@
"types/*": ["types/*"],
}
},
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"],
"exclude": ["node_modules", ".next"]
}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index d28a886..aaf561c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -347,11 +347,24 @@
suspend-react "^0.0.8"
zustand "^3.7.1"
+"@resvg/resvg-wasm@2.4.1":
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/@resvg/resvg-wasm/-/resvg-wasm-2.4.1.tgz#88f7a08107bf5ea691b016e55e6db955c85d845c"
+ integrity sha512-yi6R0HyHtsoWTRA06Col4WoDs7SvlXU3DLMNP2bdAgs7HK18dTEVl1weXgxRzi8gwLteGUbIg29zulxIB3GSdg==
+
"@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"
integrity sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==
+"@shuding/opentype.js@1.4.0-beta.0":
+ version "1.4.0-beta.0"
+ resolved "https://registry.yarnpkg.com/@shuding/opentype.js/-/opentype.js-1.4.0-beta.0.tgz#5d1e7e9e056f546aad41df1c5043f8f85d39e24b"
+ integrity sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==
+ dependencies:
+ fflate "^0.7.3"
+ string.prototype.codepointat "^0.2.1"
+
"@swc/helpers@0.4.14":
version "0.4.14"
resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.14.tgz#1352ac6d95e3617ccb7c1498ff019654f1e12a74"
@@ -614,6 +627,15 @@
dependencies:
"@use-gesture/core" "10.2.26"
+"@vercel/og@^0.5.4":
+ version "0.5.4"
+ resolved "https://registry.yarnpkg.com/@vercel/og/-/og-0.5.4.tgz#71de6335b94d0032b325936337c0259d85b9de19"
+ integrity sha512-o4Zjgw66HPtfGFYG4CFcKfnCcK6qCY+3FC6g22Z1SdAN5jN8XjbHCh3hRVHH5IGBQp8mxH941EcH53KimAm+wg==
+ dependencies:
+ "@resvg/resvg-wasm" "2.4.1"
+ satori "0.7.2"
+ yoga-wasm-web "0.3.3"
+
"@webgpu/glslang@^0.0.15":
version "0.0.15"
resolved "https://registry.yarnpkg.com/@webgpu/glslang/-/glslang-0.0.15.tgz#f5ccaf6015241e6175f4b90906b053f88483d1f2"
@@ -868,6 +890,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@0.0.8:
+ version "0.0.8"
+ resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978"
+ integrity sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==
+
base64-js@^1.3.0, base64-js@^1.3.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
@@ -980,6 +1007,11 @@ camelcase-css@^2.0.1:
resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5"
integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
+camelize@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3"
+ integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==
+
camera-controls@^2.3.1:
version "2.3.4"
resolved "https://registry.yarnpkg.com/camera-controls/-/camera-controls-2.3.4.tgz#f372b5a4012b474df0ed0c67da7a3198d7efee0b"
@@ -1175,6 +1207,30 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
+css-background-parser@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/css-background-parser/-/css-background-parser-0.1.0.tgz#48a17f7fe6d4d4f1bca3177ddf16c5617950741b"
+ integrity sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==
+
+css-box-shadow@1.0.0-3:
+ version "1.0.0-3"
+ resolved "https://registry.yarnpkg.com/css-box-shadow/-/css-box-shadow-1.0.0-3.tgz#9eaeb7140947bf5d649fc49a19e4bbaa5f602713"
+ integrity sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==
+
+css-color-keywords@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05"
+ integrity sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==
+
+css-to-react-native@^3.0.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.2.0.tgz#cdd8099f71024e149e4f6fe17a7d46ecd55f1e32"
+ integrity sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==
+ dependencies:
+ camelize "^1.0.0"
+ css-color-keywords "^1.0.0"
+ postcss-value-parser "^4.0.2"
+
cssesc@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
@@ -1400,6 +1456,11 @@ electron-to-chromium@^1.4.284:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.365.tgz#ccd9e352d4493aa288d87e6ea36f3edf350c045e"
integrity sha512-FRHZO+1tUNO4TOPXmlxetkoaIY8uwHzd1kKopK/Gx2SKn1L47wJXWD44wxP5CGRyyP98z/c8e1eBzJrgPeiBOg==
+emoji-regex@^10.2.1:
+ version "10.2.1"
+ resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.2.1.tgz#a41c330d957191efd3d9dfe6e1e8e1e9ab048b3f"
+ integrity sha512-97g6QgOk8zlDRdgq1WxwgTMgEWGVAQvB5Fdpgc1MkNy56la5SKP9GsMXKDOdqwn90/41a8yPwIGk1Y6WVbeMQA==
+
emoji-regex@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
@@ -1841,6 +1902,11 @@ fflate@^0.6.9, fflate@~0.6.9:
resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.6.10.tgz#5f40f9659205936a2d18abf88b2e7781662b6d43"
integrity sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==
+fflate@^0.7.3:
+ version "0.7.4"
+ resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.7.4.tgz#61587e5d958fdabb5a9368a302c25363f4f69f50"
+ integrity sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==
+
figures@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af"
@@ -2349,6 +2415,11 @@ hastscript@^7.0.0:
property-information "^6.0.0"
space-separated-tokens "^2.0.0"
+hex-rgb@^4.1.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/hex-rgb/-/hex-rgb-4.3.0.tgz#af5e974e83bb2fefe44d55182b004ec818c07776"
+ integrity sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==
+
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"
@@ -2899,6 +2970,14 @@ lilconfig@^2.0.5, lilconfig@^2.0.6:
resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52"
integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==
+linebreak@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/linebreak/-/linebreak-1.1.0.tgz#831cf378d98bced381d8ab118f852bd50d81e46b"
+ integrity sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==
+ dependencies:
+ base64-js "0.0.8"
+ unicode-trie "^2.0.0"
+
lines-and-columns@^1.1.6:
version "1.2.4"
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
@@ -3778,6 +3857,11 @@ p-map@^4.0.0:
dependencies:
aggregate-error "^3.0.0"
+pako@^0.2.5:
+ version "0.2.9"
+ resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
+ integrity sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==
+
parent-module@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
@@ -3785,6 +3869,14 @@ parent-module@^1.0.0:
dependencies:
callsites "^3.0.0"
+parse-css-color@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/parse-css-color/-/parse-css-color-0.2.1.tgz#b687a583f2e42e66ffdfce80a570706966e807c9"
+ integrity sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==
+ dependencies:
+ color-name "^1.1.4"
+ hex-rgb "^4.1.0"
+
parse-entities@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-4.0.1.tgz#4e2a01111fb1c986549b944af39eeda258fc9e4e"
@@ -3911,7 +4003,7 @@ postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.11:
cssesc "^3.0.0"
util-deprecate "^1.0.2"
-postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0:
+postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
@@ -4406,6 +4498,21 @@ safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
+satori@0.7.2:
+ version "0.7.2"
+ resolved "https://registry.yarnpkg.com/satori/-/satori-0.7.2.tgz#1d935f3520ad22009b7b19e4c2e73c55660d6534"
+ integrity sha512-Eltg0/i3OEbBLaveCnYi2j+p0J9Bb5rmDMXddq4Zy0/NYHbpTkPIlPYGgb+DKamhmvXhiGvWGiFdqHVjJCaCpA==
+ dependencies:
+ "@shuding/opentype.js" "1.4.0-beta.0"
+ css-background-parser "^0.1.0"
+ css-box-shadow "1.0.0-3"
+ css-to-react-native "^3.0.0"
+ emoji-regex "^10.2.1"
+ linebreak "^1.1.0"
+ parse-css-color "^0.2.1"
+ postcss-value-parser "^4.2.0"
+ yoga-wasm-web "^0.3.3"
+
scheduler@^0.21.0:
version "0.21.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.21.0.tgz#6fd2532ff5a6d877b6edb12f00d8ab7e8f308820"
@@ -4777,7 +4884,7 @@ tiny-glob@^0.2.9:
globalyzer "0.1.0"
globrex "^0.1.2"
-tiny-inflate@^1.0.3:
+tiny-inflate@^1.0.0, tiny-inflate@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/tiny-inflate/-/tiny-inflate-1.0.3.tgz#122715494913a1805166aaf7c93467933eea26c4"
integrity sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==
@@ -4924,6 +5031,14 @@ unbox-primitive@^1.0.2:
has-symbols "^1.0.3"
which-boxed-primitive "^1.0.2"
+unicode-trie@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/unicode-trie/-/unicode-trie-2.0.0.tgz#8fd8845696e2e14a8b67d78fa9e0dd2cad62fec8"
+ integrity sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==
+ dependencies:
+ pako "^0.2.5"
+ tiny-inflate "^1.0.0"
+
unified@^10.0.0:
version "10.1.2"
resolved "https://registry.yarnpkg.com/unified/-/unified-10.1.2.tgz#b1d64e55dafe1f0b98bb6c719881103ecf6c86df"
@@ -5234,6 +5349,11 @@ yocto-queue@^0.1.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
+yoga-wasm-web@0.3.3, yoga-wasm-web@^0.3.3:
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/yoga-wasm-web/-/yoga-wasm-web-0.3.3.tgz#eb8e9fcb18e5e651994732f19a220cb885d932ba"
+ integrity sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==
+
zstddec@^0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/zstddec/-/zstddec-0.0.2.tgz#57e2f28dd1ff56b750e07d158a43f0611ad9eeb4"