feat: switch OG images to vercel edge runtime + Satori

This commit is contained in:
Travis Fischer
2022-10-14 17:32:42 -04:00
parent 07d84bd5ea
commit 04b9c581a3
9 changed files with 383 additions and 416 deletions

View File

@@ -6,7 +6,7 @@
*/
import { parsePageId } from 'notion-utils'
import posthog from 'posthog-js'
import type posthog from 'posthog-js'
import { getEnv, getSiteConfig } from './get-config-value'
import { NavigationLink } from './site-config'
import {
@@ -131,6 +131,7 @@ export const apiBaseUrl = `/api`
export const api = {
searchNotion: `${apiBaseUrl}/search-notion`,
getNotionPageInfo: `${apiBaseUrl}/notion-page-info`,
getSocialImage: `${apiBaseUrl}/social-image`
}

File diff suppressed because one or more lines are too long

View File

@@ -60,3 +60,13 @@ export interface PageUrlOverridesInverseMap {
// (this overrides the built-in URL path generation for these pages)
[pageId: string]: string
}
export interface NotionPageInfo {
pageId: string
title: string
image: string
imageObjectPosition: string
author: string
authorImage: string
detail: string
}

View File

@@ -29,6 +29,7 @@
"@keyvhq/core": "^1.6.9",
"@keyvhq/redis": "^1.6.10",
"@react-icons/all-files": "^4.1.0",
"@vercel/og": "^0.0.18",
"classnames": "^2.3.1",
"date-fns": "^2.28.0",
"expiry-map": "^2.0.0",
@@ -37,7 +38,6 @@
"isomorphic-unfetch": "^3.1.0",
"lqip-modern": "^1.2.0",
"next": "^12.3.1",
"next-api-og-image": "^2.2.1",
"notion-client": "^6.13.11",
"notion-types": "^6.13.4",
"notion-utils": "^6.13.4",
@@ -67,15 +67,7 @@
"prettier": "^2.7.1",
"typescript": "^4.8.4"
},
"resolutions": {
"next-api-og-image/chrome-aws-lambda": "6.0.0",
"next-api-og-image/puppeteer-core": "6.0.0"
},
"overrides": {
"next-api-og-image": {
"chrome-aws-lambda": "6.0.0",
"puppeteer-core": "6.0.0"
},
"cacheable-request": {
"keyv": "npm:@keyvhq/core@~1.6.6"
}

View File

@@ -0,0 +1,113 @@
import { NextApiRequest, NextApiResponse } from 'next'
import {
getBlockTitle,
getBlockIcon,
getPageProperty,
isUrl,
parsePageId
} from 'notion-utils'
import { PageBlock } from 'notion-types'
import { notion } from 'lib/notion-api'
import { mapImageUrl } from 'lib/map-image-url'
import { NotionPageInfo } from 'lib/types'
import * as libConfig from 'lib/config'
export default async (req: NextApiRequest, res: NextApiResponse) => {
if (req.method !== 'POST') {
return res.status(405).send({ error: 'method not allowed' })
}
const pageId: string = parsePageId(req.body.pageId)
if (!pageId) {
throw new Error('Invalid notion page id')
}
const recordMap = await notion.getPage(pageId)
const keys = Object.keys(recordMap?.block || {})
const block = recordMap?.block?.[keys[0]]?.value
if (!block) {
throw new Error('Invalid recordMap for page')
}
const blockSpaceId = block.space_id
if (
blockSpaceId &&
libConfig.rootNotionSpaceId &&
blockSpaceId !== libConfig.rootNotionSpaceId
) {
return res.status(400).send({
error: `Notion page "${pageId}" belongs to a different workspace.`
})
}
const isBlogPost =
block.type === 'page' && block.parent_table === 'collection'
const title = getBlockTitle(block, recordMap) || libConfig.name
const image = mapImageUrl(
getPageProperty<string>('Social Image', block, recordMap) ||
(block as PageBlock).format?.page_cover ||
libConfig.defaultPageCover,
block
)
const imageCoverPosition =
(block as PageBlock).format?.page_cover_position ??
libConfig.defaultPageCoverPosition
const imageObjectPosition = imageCoverPosition
? `center ${(1 - imageCoverPosition) * 100}%`
: null
const blockIcon = getBlockIcon(block, recordMap)
const authorImage = mapImageUrl(
blockIcon && isUrl(blockIcon) ? blockIcon : libConfig.defaultPageIcon,
block
)
const author =
getPageProperty<string>('Author', block, recordMap) || libConfig.author
// const socialDescription =
// getPageProperty<string>('Description', block, recordMap) ||
// libConfig.description
// const lastUpdatedTime = getPageProperty<number>(
// 'Last Updated',
// block,
// recordMap
// )
const publishedTime = getPageProperty<number>('Published', block, recordMap)
const datePublished = publishedTime ? new Date(publishedTime) : undefined
// const dateUpdated = lastUpdatedTime
// ? new Date(lastUpdatedTime)
// : publishedTime
// ? new Date(publishedTime)
// : undefined
const date =
isBlogPost && datePublished
? `${datePublished.toLocaleString('en-US', {
month: 'long'
})} ${datePublished.getFullYear()}`
: undefined
const detail = date || author || libConfig.domain
const pageInfo: NotionPageInfo = {
pageId,
title,
image,
imageObjectPosition,
author,
authorImage,
detail
}
res.setHeader(
'Cache-Control',
'public, s-maxage=30, max-age=30, stale-while-revalidate=30'
)
res.status(200).json(pageInfo)
}

View File

@@ -1,251 +1,172 @@
import * as React from 'react'
import { withOGImage } from 'next-api-og-image'
import { ImageResponse } from '@vercel/og'
import { NextRequest } from 'next/server'
import {
getBlockTitle,
getBlockIcon,
getPageProperty,
isUrl,
parsePageId
} from 'notion-utils'
import { PageBlock } from 'notion-types'
import { NotionPageInfo } from 'lib/types'
import { host, api } from 'lib/config'
import { notion } from 'lib/notion-api'
import { mapImageUrl } from 'lib/map-image-url'
import { interRegular } from 'lib/fonts'
import * as config from 'lib/config'
const interRegularFontP = fetch(
new URL('../../public/fonts/Inter-Regular.ttf', import.meta.url)
).then((res) => res.arrayBuffer())
/**
* Social image generation via headless chrome.
*
* Note: To debug social images, set `debugInspectHtml` to true and load a social
* image URL. Instead of returning the rendered image, it will return the raw HTML
* that would've been passed to puppeteer. This makes it much easier to develop
* and debug issues locally.
*/
const debugInspectHtml = false
const interBoldFontP = fetch(
new URL('../../public/fonts/Inter-SemiBold.ttf', import.meta.url)
).then((res) => res.arrayBuffer())
export default withOGImage<'query', 'id'>({
template: {
react: async ({ id }) => {
const pageId = parsePageId(id)
export const config = {
runtime: 'experimental-edge'
}
if (!pageId) {
throw new Error('Invalid notion page id')
}
export default async function OGImage(req: NextRequest) {
const [interRegularFont, interBoldFont] = await Promise.all([
interRegularFontP,
interBoldFontP
])
const recordMap = await notion.getPage(pageId)
const keys = Object.keys(recordMap?.block || {})
const block = recordMap?.block?.[keys[0]]?.value
if (!block) {
throw new Error('Invalid recordMap for page')
}
const isBlogPost =
block.type === 'page' && block.parent_table === 'collection'
const title = getBlockTitle(block, recordMap) || config.name
const image = mapImageUrl(
getPageProperty<string>('Social Image', block, recordMap) ||
(block as PageBlock).format?.page_cover ||
config.defaultPageCover,
block
)
const imageCoverPosition =
(block as PageBlock).format?.page_cover_position ??
config.defaultPageCoverPosition
const imageObjectPosition = imageCoverPosition
? `center ${(1 - imageCoverPosition) * 100}%`
: null
const blockIcon = getBlockIcon(block, recordMap)
const authorImage = mapImageUrl(
blockIcon && isUrl(blockIcon) ? blockIcon : config.defaultPageIcon,
block
)
const author =
getPageProperty<string>('Author', block, recordMap) || config.author
// const socialDescription =
// getPageProperty<string>('Description', block, recordMap) ||
// config.description
const lastUpdatedTime = getPageProperty<number>(
'Last Updated',
block,
recordMap
)
const publishedTime = getPageProperty<number>(
'Published',
block,
recordMap
)
const dateUpdated = lastUpdatedTime
? new Date(lastUpdatedTime)
: publishedTime
? new Date(publishedTime)
: undefined
const date =
isBlogPost && dateUpdated
? `${dateUpdated.toLocaleString('en-US', {
month: 'long'
})} ${dateUpdated.getFullYear()}`
: undefined
const detail = date || config.domain
return (
<html>
<head>
<style dangerouslySetInnerHTML={{ __html: style }} />
</head>
<body>
<div className='container'>
<div className='horiz'>
<div className='lhs'>
<div className='main'>
<h1 className='title'>{title}</h1>
</div>
<div className='metadata'>
{authorImage && (
<div
className='author-image'
style={{ backgroundImage: `url(${authorImage})` }}
/>
)}
{(author || detail) && (
<div className='metadata-rhs'>
{author && <div className='author'>{author}</div>}
{detail && <div className='detail'>{detail}</div>}
</div>
)}
</div>
</div>
{image && (
<img
src={image}
className='rhs'
style={{
objectPosition: imageObjectPosition || undefined
}}
/>
)}
</div>
</div>
</body>
</html>
)
}
},
cacheControl: 'max-age=0, s-maxage=86400, stale-while-revalidate=3600',
type: 'jpeg',
quality: 75,
dev: {
inspectHtml: debugInspectHtml
const { searchParams } = new URL(req.url)
const pageId = searchParams.get('id')
if (!pageId) {
return new Response('Invalid notion page id', { status: 400 })
}
})
const style = `
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: normal;
src: url(data:font/woff2;charset=utf-8;base64,${interRegular}) format('woff2');
}
const pageInfoRes = await fetch(`${host}${api.getNotionPageInfo}`, {
method: 'POST',
body: JSON.stringify({ pageId }),
headers: { 'Content-Type': 'application/json' }
})
const pageInfo: NotionPageInfo = await pageInfoRes.json()
:root {
--padding: 8vmin;
}
return new ImageResponse(
(
<div
style={{
position: 'relative',
width: '100%',
height: '100%',
display: 'flex',
flexDirection: 'column',
backgroundColor: '#1F2027',
alignItems: 'center',
justifyContent: 'center',
fontFamily: '"Inter", sans-serif',
color: 'black'
}}
>
{pageInfo.image && (
<img
src={pageInfo.image}
style={{
position: 'absolute',
width: '100%',
height: '100%',
objectFit: 'cover'
// TODO: satori doesn't support background-size: cover and seems to
// have inconsistent support for filter + transform to get rid of the
// blurred edges. For now, we'll go without a blur filter on the
// background, but Satori is still very new, so hopefully we can re-add
// the blur soon.
* {
box-sizing: border-box;
}
// backgroundImage: pageInfo.image
// ? `url(${pageInfo.image})`
// : undefined,
// backgroundSize: '100% 100%'
// TODO: pageInfo.imageObjectPosition
// filter: 'blur(8px)'
// transform: 'scale(1.05)'
}}
/>
)}
body {
font-family: 'Inter', sans-serif;
padding: 0;
margin: 0;
}
<div
style={{
position: 'relative',
width: 900,
height: 450,
display: 'flex',
flexDirection: 'column',
border: '16px solid rgba(0,0,0,0.3)',
borderRadius: 8,
zIndex: '1'
}}
>
<div
style={{
width: '100%',
height: '100%',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-around',
backgroundColor: '#fff',
padding: 24,
alignItems: 'center',
textAlign: 'center'
}}
>
{pageInfo.detail && (
<div style={{ fontSize: 32, opacity: 0 }}>{pageInfo.detail}</div>
)}
.container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: var(--padding);
background: #1F2027;
color: #fff;
}
<div
style={{
fontSize: 70,
fontWeight: 700,
fontFamily: 'Inter'
}}
>
{pageInfo.title}
</div>
.horiz {
display: flex;
flex-direction: row;
justify-content: space-between;
gap: var(--padding);
width: 100%;
height: 100%;
}
{pageInfo.detail && (
<div style={{ fontSize: 32, opacity: 0.6 }}>
{pageInfo.detail}
</div>
)}
</div>
</div>
.lhs {
display: flex;
flex-direction: column;
justify-content: space-between;
{pageInfo.authorImage && (
<div
style={{
position: 'absolute',
top: 32,
left: 104,
height: 128,
width: 128,
display: 'flex',
borderRadius: '50%',
border: '4px solid #fff',
zIndex: '5'
}}
>
<img
src={pageInfo.authorImage}
style={{
width: '100%',
height: '100%'
// transform: 'scale(1.04)'
}}
/>
</div>
)}
</div>
),
{
width: 1200,
height: 600,
fonts: [
{
name: 'Inter',
data: interRegularFont,
style: 'normal',
weight: 400
},
{
name: 'Inter',
data: interBoldFont,
style: 'normal',
weight: 700
}
]
}
)
}
.rhs {
width: 35%;
height: 100%;
border-radius: 4px;
object-fit: cover;
}
.title {
font-size: 3.2em;
line-height: 1.3;
}
.metadata {
color: #A9ACC0;
display: flex;
flex-direction: row;
align-items: center;
gap: calc(var(--padding) * 0.7);
font-size: 1.5em;
}
.author {
font-size: 1.75em;
}
.author-image {
background-size: cover;
width: 20vmin;
min-width: 20vmin;
max-width: 20vmin;
height: 20vmin;
min-height: 20vmin;
max-height: 20vmin;
border-radius: 50%;
border: 1.5vmin solid #fff;
}
.metadata-rhs {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
gap: 0.5em;
}
.detail {
overflow-wrap: break-word;
}
`

Binary file not shown.

Binary file not shown.

271
yarn.lock
View File

@@ -189,11 +189,24 @@
resolved "https://registry.npmjs.org/@react-icons/all-files/-/all-files-4.1.0.tgz"
integrity sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ==
"@resvg/resvg-wasm@2.0.0-alpha.4":
version "2.0.0-alpha.4"
resolved "https://registry.yarnpkg.com/@resvg/resvg-wasm/-/resvg-wasm-2.0.0-alpha.4.tgz#fc2f86186a9641df030d8f9f3f9d995899cd1ecb"
integrity sha512-pWIG9a/x1ky8gXKRhPH1OPKpHFoMN1ISLbJ+O+gPXQHIAKhNd5I28RlWf7q576hAOQA9JZTlo3p/M2uyLzJmmw==
"@sentry/types@^6.11.0":
version "6.19.4"
resolved "https://registry.npmjs.org/@sentry/types/-/types-6.19.4.tgz"
integrity sha512-fzLiQPrjJQ8HgFgA2VqnpLiEOrTJ2ItRY8RY7Cn4038HACoYWYDjrkdVJQBq6IyrxxkgWOSLZXnv85uozBQC+g==
"@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"
"@sindresorhus/is@^4.0.0", "@sindresorhus/is@^4.6.0":
version "4.6.0"
resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz"
@@ -300,6 +313,11 @@
dependencies:
"@types/node" "*"
"@types/yoga-layout@1.9.2":
version "1.9.2"
resolved "https://registry.yarnpkg.com/@types/yoga-layout/-/yoga-layout-1.9.2.tgz#efaf9e991a7390dc081a0b679185979a83a9639a"
integrity sha512-S9q47ByT2pPvD65IvrWp7qppVMpk9WGMbVq9wbWZOHg6tnXSD4vyhao6nOSBwwfDdV2p3Kx9evA9vI+XWTfDvw==
"@typescript-eslint/eslint-plugin@^5.40.0":
version "5.40.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.40.0.tgz#0159bb71410eec563968288a17bd4478cdb685bd"
@@ -386,16 +404,20 @@
resolved "https://registry.npmjs.org/@use-it/event-listener/-/event-listener-0.1.7.tgz"
integrity sha512-hgfExDzUU9uTRTPDCpw2s9jWTxcxmpJya3fK5ADpf5VDpSy8WYwY/kh28XE0tUcbsljeP8wfan48QvAQTSSa3Q==
"@vercel/og@^0.0.18":
version "0.0.18"
resolved "https://registry.yarnpkg.com/@vercel/og/-/og-0.0.18.tgz#4ee97eaf1f1fc2350447d3b43a1e4ee0c970de64"
integrity sha512-cEid22FkiNrgJ/HtawA6V3+x2jhP+KqwwNG97afFsFmZ/oPsh3Bm01NzCVSpeR96/aPaT2/59pbFXGxulxgp7g==
dependencies:
"@resvg/resvg-wasm" "2.0.0-alpha.4"
satori "0.0.40"
yoga-wasm-web "0.1.2"
"@xobotyi/scrollbar-width@^1.9.5":
version "1.9.5"
resolved "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz"
integrity sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==
"@yarnpkg/lockfile@^1.1.0":
version "1.1.0"
resolved "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz"
integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==
acorn-jsx@^5.3.2:
version "5.3.2"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
@@ -616,12 +638,17 @@ callsites@^3.0.0:
resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
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==
caniuse-lite@^1.0.30001406:
version "1.0.30001419"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001419.tgz#3542722d57d567c8210d5e4d0f9f17336b776457"
integrity sha512-aFO1r+g6R7TW+PNQxKzjITwLOyDhVRLjW0LcwS/HCZGUUKTGNp9+IwLC4xyDSZBygVL/mxaFR3HIV6wEKQuSzw==
chalk@^2.4.1, chalk@^2.4.2:
chalk@^2.4.1:
version "2.4.2"
resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@@ -643,18 +670,13 @@ chownr@^1.1.1:
resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz"
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
chrome-aws-lambda@6.0.0, chrome-aws-lambda@^10.1.0:
chrome-aws-lambda@6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/chrome-aws-lambda/-/chrome-aws-lambda-6.0.0.tgz#e0966a5759e6b57c24584c2511fb72738b6209ff"
integrity sha512-XnFo6AaE5ZYpHYmOmMoj1yCYFeRTx6uFCpJnVuDREWzXevzZvo3gzkyQ6qSKsPW91VGWeQI7wQgnOpW50e+Dzg==
dependencies:
lambdafs "^2.0.2"
ci-info@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz"
integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
classnames@^2.3.1:
version "2.3.1"
resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz"
@@ -796,6 +818,21 @@ cross-spawn@^7.0.1, cross-spawn@^7.0.2:
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-in-js-utils@^2.0.0:
version "2.0.1"
resolved "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz"
@@ -804,6 +841,15 @@ css-in-js-utils@^2.0.0:
hyphenate-style-name "^1.0.2"
isobject "^3.0.1"
css-to-react-native@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz#62dbe678072a824a689bcfee011fc96e02a7d756"
integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==
dependencies:
camelize "^1.0.0"
css-color-keywords "^1.0.0"
postcss-value-parser "^4.0.2"
css-tree@^1.1.2:
version "1.1.3"
resolved "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz"
@@ -853,11 +899,6 @@ deep-is@^0.1.3:
resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz"
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
deepmerge@^4.2.2:
version "4.2.2"
resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz"
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
defer-to-connect@^2.0.0, defer-to-connect@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz"
@@ -1275,6 +1316,11 @@ fflate@^0.4.1:
resolved "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz"
integrity sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==
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==
file-entry-cache@^6.0.1:
version "6.0.1"
resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz"
@@ -1313,13 +1359,6 @@ find-up@^5.0.0:
locate-path "^6.0.0"
path-exists "^4.0.0"
find-yarn-workspace-root@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz"
integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==
dependencies:
micromatch "^4.0.2"
flat-cache@^3.0.4:
version "3.0.4"
resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz"
@@ -1343,24 +1382,6 @@ fs-constants@^1.0.0:
resolved "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz"
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
fs-extra@^7.0.1:
version "7.0.1"
resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz"
integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==
dependencies:
graceful-fs "^4.1.2"
jsonfile "^4.0.0"
universalify "^0.1.0"
fs-extra@^8.0.1:
version "8.1.0"
resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz"
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^4.0.0"
universalify "^0.1.0"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
@@ -1524,7 +1545,7 @@ got@^12.0.3:
p-cancelable "^3.0.0"
responselike "^2.0.0"
graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0:
graceful-fs@^4.1.2:
version "4.2.9"
resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz"
integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==
@@ -1760,13 +1781,6 @@ is-callable@^1.2.7:
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
is-ci@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz"
integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==
dependencies:
ci-info "^2.0.0"
is-core-module@^2.2.0, is-core-module@^2.8.1:
version "2.8.1"
resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz"
@@ -1781,11 +1795,6 @@ is-date-object@^1.0.1:
dependencies:
has-tostringtag "^1.0.0"
is-docker@^2.0.0:
version "2.2.1"
resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz"
integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz"
@@ -1868,13 +1877,6 @@ is-weakref@^1.0.2:
dependencies:
call-bind "^1.0.2"
is-wsl@^2.1.1:
version "2.2.0"
resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz"
integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
dependencies:
is-docker "^2.0.0"
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
@@ -1945,22 +1947,6 @@ json5@^2.1.2:
resolved "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz"
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz"
integrity "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="
optionalDependencies:
graceful-fs "^4.1.6"
jsonfile@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-5.0.0.tgz"
integrity sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==
dependencies:
universalify "^0.1.2"
optionalDependencies:
graceful-fs "^4.1.6"
"jsx-ast-utils@^2.4.1 || ^3.0.0":
version "3.2.1"
resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz"
@@ -1984,13 +1970,6 @@ keyv@^4.0.0:
compress-brotli "^1.3.6"
json-buffer "3.0.1"
klaw-sync@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz"
integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==
dependencies:
graceful-fs "^4.1.11"
lambdafs@^2.0.2:
version "2.1.1"
resolved "https://registry.npmjs.org/lambdafs/-/lambdafs-2.1.1.tgz"
@@ -2153,7 +2132,7 @@ merge2@^1.3.0, merge2@^1.4.1:
resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
micromatch@^4.0.2, micromatch@^4.0.4:
micromatch@^4.0.4:
version "4.0.5"
resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz"
integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
@@ -2249,17 +2228,6 @@ natural-compare@^1.4.0:
resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
integrity "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
next-api-og-image@^2.2.1:
version "2.2.1"
resolved "https://registry.npmjs.org/next-api-og-image/-/next-api-og-image-2.2.1.tgz"
integrity sha512-cpxHkShMpQpivL/GEPxvxZ+jS2+HxAtRdpaqAcDbLZpeLdpnbZtZW7p6PUuAe6GGIdZdfjeOmuy0ivXdPobIQQ==
dependencies:
chrome-aws-lambda "^10.1.0"
deepmerge "^4.2.2"
patch-package "^6.4.7"
puppeteer-core "^10.4.0"
twemoji "^13.1.0"
next@^12.3.1:
version "12.3.1"
resolved "https://registry.yarnpkg.com/next/-/next-12.3.1.tgz#127b825ad2207faf869b33393ec8c75fe61e50f1"
@@ -2468,14 +2436,6 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0:
dependencies:
wrappy "1"
open@^7.4.2:
version "7.4.2"
resolved "https://registry.npmjs.org/open/-/open-7.4.2.tgz"
integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==
dependencies:
is-docker "^2.0.0"
is-wsl "^2.1.1"
opener@^1.5.2:
version "1.5.2"
resolved "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz"
@@ -2493,11 +2453,6 @@ optionator@^0.9.1:
type-check "^0.4.0"
word-wrap "^1.2.3"
os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz"
integrity "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g=="
p-cancelable@^2.0.0:
version "2.1.1"
resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz"
@@ -2614,25 +2569,6 @@ parse-json@^4.0.0:
error-ex "^1.3.1"
json-parse-better-errors "^1.0.1"
patch-package@^6.4.7:
version "6.4.7"
resolved "https://registry.npmjs.org/patch-package/-/patch-package-6.4.7.tgz"
integrity sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==
dependencies:
"@yarnpkg/lockfile" "^1.1.0"
chalk "^2.4.2"
cross-spawn "^6.0.5"
find-yarn-workspace-root "^2.0.0"
fs-extra "^7.0.1"
is-ci "^2.0.0"
klaw-sync "^6.0.0"
minimist "^1.2.0"
open "^7.4.2"
rimraf "^2.6.3"
semver "^5.6.0"
slash "^2.0.0"
tmp "^0.0.33"
path-exists@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
@@ -2707,6 +2643,11 @@ pkg-dir@^4.2.0:
dependencies:
find-up "^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==
postcss@8.4.14:
version "8.4.14"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz"
@@ -2796,7 +2737,7 @@ punycode@^2.1.0:
resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
puppeteer-core@6.0.0, puppeteer-core@^10.4.0:
puppeteer-core@6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-6.0.0.tgz#16fea8229ee4053f208194cd17718318ea6e69a7"
integrity sha512-Mm4lVSM8CJUrHSLt2zHjlW9B2D5B3JRbkbmxzGaGTauaB9gTrM+r7gk88xfRWuaBy81pRG+nTtCBdMPzO7pjqg==
@@ -3094,13 +3035,6 @@ reusify@^1.0.4:
resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz"
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
rimraf@^2.6.3:
version "2.7.1"
resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz"
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
dependencies:
glob "^7.1.3"
rimraf@^3.0.2:
version "3.0.2"
resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz"
@@ -3149,6 +3083,18 @@ safe-regex-test@^1.0.0:
get-intrinsic "^1.1.3"
is-regex "^1.1.4"
satori@0.0.40:
version "0.0.40"
resolved "https://registry.yarnpkg.com/satori/-/satori-0.0.40.tgz#cc9c4b1c87820f4f62f90c9533d879cc74eb0194"
integrity sha512-SoXGq/89mBU34U1h4g/nXeL9DHS/Aof2iUL3FHabq+laSRQUSUI1ZhPhak3J6VMNW8wghYwJ/Bi7aF8FLPq9qQ==
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"
postcss-value-parser "^4.2.0"
yoga-layout-prebuilt "^1.10.0"
scheduler@^0.23.0:
version "0.23.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
@@ -3170,7 +3116,7 @@ screenfull@^5.1.0:
resolved "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz"
integrity sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==
"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0:
"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0:
version "5.7.1"
resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@@ -3291,11 +3237,6 @@ sirv@^1.0.7:
mrmime "^1.0.0"
totalist "^1.0.0"
slash@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz"
integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==
slash@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz"
@@ -3390,6 +3331,11 @@ string-width@^1.0.1, "string-width@^1.0.2 || 2 || 3 || 4":
is-fullwidth-code-point "^1.0.0"
strip-ansi "^3.0.0"
string.prototype.codepointat@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz#004ad44c8afc727527b108cd462b4d971cd469bc"
integrity sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==
string.prototype.matchall@^4.0.7:
version "4.0.7"
resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz#8e6ecb0d8a1fb1fda470d81acecb2dba057a481d"
@@ -3558,13 +3504,6 @@ tiny-warning@^1.0.0:
resolved "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz"
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz"
integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
dependencies:
os-tmpdir "~1.0.2"
to-regex-range@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz"
@@ -3621,21 +3560,6 @@ tunnel-agent@^0.6.0:
dependencies:
safe-buffer "^5.0.1"
twemoji-parser@13.1.0:
version "13.1.0"
resolved "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-13.1.0.tgz"
integrity sha512-AQOzLJpYlpWMy8n+0ATyKKZzWlZBJN+G0C+5lhX7Ftc2PeEVdUU/7ns2Pn2vVje26AIZ/OHwFoUbdv6YYD/wGg==
twemoji@^13.1.0:
version "13.1.1"
resolved "https://registry.npmjs.org/twemoji/-/twemoji-13.1.1.tgz"
integrity sha512-IIIoq+n1lk1M1+evBKZD3DO0ud02fDQ4ssbgAv8rp3YBWUeNmskjlisFUPPDacQ50XS3bhrd4Kq9Q2gqhxb0dg==
dependencies:
fs-extra "^8.0.1"
jsonfile "^5.0.0"
twemoji-parser "13.1.0"
universalify "^0.1.2"
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz"
@@ -3691,11 +3615,6 @@ unionize@^2.1.2:
resolved "https://registry.npmjs.org/unionize/-/unionize-2.2.0.tgz"
integrity sha512-lHXiL6LPVuRYBGCLOdUd4GMHoAGqM0HtYHAZcA6pUEiwN1nk+LEYlh8bud7saeL0bkFntJzCPEPVVJeFm3Cqsg==
universalify@^0.1.0, universalify@^0.1.2:
version "0.1.2"
resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz"
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
uri-js@^4.2.2:
version "4.4.1"
resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz"
@@ -3832,3 +3751,15 @@ yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
yoga-layout-prebuilt@^1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/yoga-layout-prebuilt/-/yoga-layout-prebuilt-1.10.0.tgz#2936fbaf4b3628ee0b3e3b1df44936d6c146faa6"
integrity sha512-YnOmtSbv4MTf7RGJMK0FvZ+KD8OEe/J5BNnR0GHhD8J/XcG/Qvxgszm0Un6FTHWW4uHlTgP0IztiXQnGyIR45g==
dependencies:
"@types/yoga-layout" "1.9.2"
yoga-wasm-web@0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/yoga-wasm-web/-/yoga-wasm-web-0.1.2.tgz#05d3fc9cbdfd57ac9682debb5001aca075489a39"
integrity sha512-8SkgawHcA0RUbMrnhxbaQkZDBi8rMed8pQHixkFF9w32zGhAwZ9/cOHWlpYfr6RCx42Yp3siV45/jPEkJxsk6w==