Merge pull request #6 from acid-info/data

init unbody integration and use of real content
This commit is contained in:
amir houieh 2023-05-05 17:38:04 +02:00 committed by GitHub
commit bebde816ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 644 additions and 173 deletions

View File

@ -2,9 +2,7 @@
const nextConfig = {
reactStrictMode: true,
images: {
domains: [
'images.pexels.com',
],
domains: ['images.cdn.unbody.io'],
},
}

View File

@ -29,8 +29,11 @@
"@types/node": "18.15.11",
"@types/react": "18.0.35",
"@types/react-dom": "18.0.11",
"axios": "^1.4.0",
"eslint": "8.38.0",
"eslint-config-next": "13.3.0",
"graphql": "^16.6.0",
"graphql-request": "^6.0.0",
"next": "13.3.0",
"react": "18.2.0",
"react-dom": "18.2.0",

View File

@ -4,55 +4,82 @@ import styled from '@emotion/styled'
import Image from 'next/image'
import { LogosCircleIcon } from '../Icons/LogosCircleIcon'
import { useMemo } from 'react'
import { UnbodyImageBlock } from '@/lib/unbody/unbody.types'
export enum PostImageRatio {
PORTRAIT = 'portrait',
LANDSCAPE = 'landscape',
SQUARE = 'square',
}
export enum PostClassType {
ARTICLE = 'article',
PODCAST = 'podcast',
}
export enum PostStyleType {
LSD = 'lsd',
DEFAULT = 'default',
}
export enum PostSize {
SMALL = 'small',
LARGE = 'large',
}
export enum PostType {
BODY = 'body',
HEADER = 'header',
}
export type PostAppearanceProps = {
size?: PostSize
classType?: PostClassType
postType?: PostType
styleType?: PostStyleType
aspectRatio?: PostImageRatio
showImage?: boolean
}
export type PostDataProps = {
date: string
title: string
description?: string
author?: string
tags?: string[]
coverImage?: UnbodyImageBlock
}
export const PostImageRatioOptions = {
[PostImageRatio.PORTRAIT]: '9 / 16',
[PostImageRatio.LANDSCAPE]: '16 / 9',
[PostImageRatio.SQUARE]: '1 / 1',
}
export type PostProps = CommonProps &
React.HTMLAttributes<HTMLDivElement> & {
size?: 'small' | 'large'
classType?: 'article' | 'podcast'
postType?: 'body' | 'header'
styleType?: 'lsd' | 'default'
aspectRatio?: 'portrait' | 'landscape' | 'square'
showImage?: boolean
imageUrl?: string
date: Date
title: string
description?: string
author?: string
tags?: string[]
appearance?: PostAppearanceProps
data: PostDataProps
}
const getAspectRatio = (aspectRatio: PostProps['aspectRatio']) => {
switch (aspectRatio) {
case 'portrait':
return '9 / 16'
case 'landscape':
return '16 / 9'
case 'square':
return '1 / 1'
default:
return '16 / 9'
}
}
export default function Post({
size = 'small',
classType = 'article',
postType = 'body',
styleType = 'lsd',
aspectRatio = 'landscape',
showImage = true,
imageUrl,
date,
title,
description,
author,
tags = [],
appearance: {
size = PostSize.SMALL,
classType = PostClassType.ARTICLE,
postType = PostType.BODY,
styleType = PostStyleType.LSD,
aspectRatio = PostImageRatio.LANDSCAPE,
showImage = true,
} = {},
data: { coverImage, date: dateStr, title, description, author, tags = [] },
...props
}: PostProps) {
const date = new Date(dateStr)
const _title = useMemo(
() => (
<CustomTypography
variant={size === 'small' ? 'h4' : 'h2'}
variant={size === PostSize.SMALL ? 'h4' : 'h2'}
genericFontFamily="serif"
>
{title}
@ -63,7 +90,7 @@ export default function Post({
const _description = useMemo(
() =>
classType == 'article' && (
classType == PostClassType.ARTICLE && (
<CustomTypography variant="body3" genericFontFamily="sans-serif">
{description}
</CustomTypography>
@ -72,24 +99,24 @@ export default function Post({
)
const _thumbnail = useMemo(() => {
if (!showImage || !imageUrl) return null
if (!showImage || !coverImage) return null
if (postType === 'body') {
return (
<ThumbnailContainer aspectRatio={aspectRatio}>
<Thumbnail fill src={imageUrl} alt={imageUrl} />
<Thumbnail fill src={coverImage.url} alt={coverImage.alt} />
</ThumbnailContainer>
)
} else {
// TBD
return (
<ThumbnailContainer aspectRatio={aspectRatio}>
<Thumbnail fill src={imageUrl} alt={imageUrl} />
<Thumbnail fill src={coverImage.url} alt={coverImage.alt} />
{_title}
{_description}
</ThumbnailContainer>
)
}
}, [showImage, imageUrl, aspectRatio, postType, _title, _description])
}, [showImage, coverImage, aspectRatio, postType, _title, _description])
const _header = useMemo(() => {
if (postType === 'body')
@ -153,10 +180,12 @@ const Container = styled.div`
`
const ThumbnailContainer = styled.div<{
aspectRatio: PostProps['aspectRatio']
aspectRatio: PostImageRatio
}>`
aspect-ratio: ${(p) =>
p.aspectRatio ? getAspectRatio(p.aspectRatio) : '16 / 9'};
p.aspectRatio
? PostImageRatioOptions[p.aspectRatio]
: PostImageRatioOptions[PostImageRatio.PORTRAIT]};
position: relative;
width: 100%;
height: 100%;

View File

@ -1,123 +1,41 @@
import { useState } from 'react'
import { PostContainer } from '../PostContainer'
import { PostProps } from './Post'
import { PostDataProps, PostProps } from './Post'
const postsData: PostProps[] = [
{
size: 'small', // 'small' | 'large'
classType: 'article', // 'article' | 'podcast'
postType: 'body', // 'body' | 'header' => TBD
styleType: 'lsd', // 'lsd' | 'default' => WIP
aspectRatio: 'landscape', // 'portrait' | 'landscape' | 'square'
showImage: true, // true | false
imageUrl:
'https://images.pexels.com/photos/4429335/pexels-photo-4429335.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2',
date: new Date(),
title: 'Preventing an Orwellian Future with Privacy-Enhancing Technology',
description:
'We built a pedal-powered generator and controller, which is practical to use as an energy source and exercise machine in a household -- and which you can integrate into a solar PV ',
author: 'Jason Freeman',
tags: ['Privacy', 'Security', 'Liberty'],
},
{
aspectRatio: 'portrait', // different aspect ratio - portrait
imageUrl:
'https://images.pexels.com/photos/4992820/pexels-photo-4992820.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2',
date: new Date(),
title: 'How to Build a Practical Household Bike Generator',
description:
'We built a pedal-powered generator and controller, which is practical to use as an energy source and exercise machine in a household -- and which you can integrate into a solar PV',
author: 'Jason Freeman',
tags: ['Privacy', 'Security', 'Liberty'],
},
{
classType: 'podcast', // podcast
imageUrl:
'https://images.pexels.com/photos/6039256/pexels-photo-6039256.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2',
date: new Date(),
title: 'How to Build a Practical Household Bike Generator',
author: 'Jason Freeman',
tags: ['Privacy', 'Security', 'Liberty'],
},
{
showImage: false, // without image
classType: 'article',
date: new Date(),
title: 'How to Build a Practical Household Bike Generator',
description:
'We built a pedal-powered generator and controller, which is practical to use as an energy source and exercise machine in a household -- and which you can integrate into a solar PV',
author: 'Jason Freeman',
tags: ['Privacy', 'Security', 'Liberty'],
},
{
postType: 'header', // header? TBD
imageUrl:
'https://images.pexels.com/photos/6039256/pexels-photo-6039256.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2',
date: new Date(),
title: 'How to Build a Practical Household Bike Generator',
description:
'We built a pedal-powered generator and controller, which is practical to use as an energy source and exercise machine in a household -- and which you can integrate into a solar PV',
},
{
showImage: false, // without image
classType: 'article',
date: new Date(),
title: 'Satoshi breaks their silence: Inside the mind of the OG anon',
description:
"Bitcoin's creator reveals their feelings on privacy, CBDCs and their favorite NFT collection in an unprecedented interview with Acid.info",
author: 'Jason Freeman',
tags: ['Privacy', 'Security', 'Liberty'],
},
{
aspectRatio: 'square', // square
imageUrl:
'https://images.pexels.com/photos/6477673/pexels-photo-6477673.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2',
date: new Date(),
title: 'How to Build a Practical Household Bike Generator',
description:
'We built a pedal-powered generator and controller, which is practical to use as an energy source and exercise machine in a household -- and which you can integrate into a solar PV',
author: 'Jason Freeman',
tags: ['Privacy', 'Security', 'Liberty'],
},
{
// featured
imageUrl:
'https://images.pexels.com/photos/6227715/pexels-photo-6227715.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2',
date: new Date(),
title: 'How to Build a Practical Household Bike Generator',
description:
'We built a pedal-powered generator and controller, which is practical to use as an energy source and exercise machine in a household -- and which you can integrate into a solar PV',
author: 'Jason Freeman',
tags: ['Privacy', 'Security', 'Liberty'],
},
]
type Props = {
posts: PostDataProps[]
featuredPost: PostDataProps
}
const PostsDemo = (props: Props) => {
const [posts, setPosts] = useState<PostDataProps[]>(props.posts)
const PostsDemo = () => {
return (
<div style={{ marginTop: '78px' }}>
{/* For Demo purposes only. Use inline CSS and styled components temporarily */}
<PostContainer title="Featured" postsData={[postsData[7]]} />
{/*@TODO @jinho, wht PostContainer should recive an array of postData instead of only One?*/}
<PostContainer
style={{ marginTop: '108px' }}
title="Latest Posts"
postsData={[postsData[3], postsData[0], postsData[3], postsData[2]]}
/>
<PostContainer
style={{ marginTop: '16px' }}
postsData={[postsData[3], postsData[5]]}
/>
<PostContainer
style={{ marginTop: '16px' }}
postsData={[postsData[1], postsData[5], postsData[5], postsData[6]]}
/>
<PostContainer
style={{ marginTop: '108px' }}
title="Podcasts"
postsData={[postsData[2], postsData[2]]}
/>
<PostContainer
style={{ marginTop: '16px', paddingBottom: '108px' }}
postsData={[postsData[2], postsData[2], postsData[2], postsData[2]]}
title="Featured"
postsData={[
{
data: props.featuredPost,
},
]}
/>
{posts.length > 0 ? (
<PostContainer
style={{ marginTop: '108px' }}
title="Latest Posts"
postsData={posts.map((post) => ({
appearance: {},
data: post,
}))}
/>
) : (
<div style={{ marginTop: '108px', textAlign: 'center' }}>
<h3>No Posts found!</h3>
</div>
)}
</div>
)
}

View File

View File

@ -0,0 +1,26 @@
import axios, { Axios } from 'axios'
import { UnbodyExploreArgs } from './unbody.types'
export class UnbodyClient {
public client: Axios
static UNBODY_GRAPHQL_ENDPOINT = 'https://graphql.unbody.io'
constructor(apiKey: string | undefined, projectId: string | undefined) {
if (!apiKey) throw new Error('Unbody client: apiKey is required')
if (!projectId) throw new Error('Unbody client: projectId is required')
this.client = axios.create({
baseURL: UnbodyClient.UNBODY_GRAPHQL_ENDPOINT,
headers: {
Authorization: apiKey,
'X-Project-id': projectId,
'Content-Type': 'application/json',
Accept: 'application/json',
},
})
}
async request<T>(query: string): Promise<T> {
const { data } = await this.client.post<T>('', { query })
return data
}
}

View File

@ -0,0 +1,237 @@
export namespace UnbodyGraphQl {
export interface Get<T> {
Get: T
}
export namespace Additional {
interface AdditionalAnswer {
endPosition: number
hasAnswer: boolean
property: string
result: string
startPosition: number
}
interface AdditionalnumbererpretationSource {
concept: string
occurrence: number
weight: number
}
interface Additionalnumbererpretation {
source: [AdditionalnumbererpretationSource]
}
interface AdditionalFeatureProjection {
vector: [number]
}
interface AdditionalNearestNeighborsNeighbor {
concept: string
distance: number
}
interface AdditionalNearestNeighbors {
neighbors: [AdditionalNearestNeighborsNeighbor]
}
interface AdditionalSemanticPath {
concept: string
distanceToNext: number
distanceToPrevious: number
distanceToQuery: number
distanceToResult: number
}
interface AdditionalClassification {
basedOn: [string]
classifiedFields: [string]
completed: string
id: string
scope: [string]
}
export interface AdditionalProps {
certainty: number
creationTimeUnix: string
distance: number
explainScore: string
id: string
lastUpdateTimeUnix: string
score: string
vector: [number]
interpretation: Additionalnumbererpretation
nearestNeighbors: AdditionalNearestNeighbors
semanticPath: AdditionalSemanticPath
answer: AdditionalAnswer
classification: AdditionalClassification
featureProjection: AdditionalFeatureProjection
}
}
export interface BaseObject {
_additional: Additional.AdditionalProps
}
export interface BaseObjectWithRef<T> extends BaseObject {
document: Array<T>
}
export interface Beacon {
beacon: string
}
export namespace Fragments {
export interface TocItem {}
export interface FootnoteItem {}
}
export interface ImageBlock
extends BaseObjectWithRef<GoogleDoc | GoogleCalendarEvent | Beacon> {
alt: string
createdAt: string
ext: string
height: number
mimeType: string
modifiedAt: string
order: number
originalName: string
path: string[]
pathstring: string
remoteId: string
size: number
sourceId: string
url: string
width: number
}
export interface TextBlock extends BaseObjectWithRef<GoogleDoc | Beacon> {
footnotes: string | Array<Fragments.FootnoteItem>
html: string
order: number
remoteId: string
sourceId: string
tagName: string
text: string
}
export interface AudioFile
extends BaseObjectWithRef<GoogleDoc | GoogleCalendarEvent | Beacon> {
duration: number
ext: string
mimeType: string
order: number
originalName: string
remoteId: string
size: number
sourceId: string
url: string
}
export interface GoogleDoc extends BaseObject {
blocks: Array<ImageBlock | TextBlock>
createdAt: string
html: string
mimeType: string
modifiedAt: string
originalName: string
path: string[]
pathstring: string
remoteId: string
size: number
sourceId: string
subtitle: string
summary: string
tags: string[]
text: string
title: string
toc: string | Array<Fragments.TocItem>
}
export interface GoogleCalendarEvent extends BaseObject {
createdAt: string
creatorDisplayName: string
creatorEmail: string
creatorId: string
creatorSelf: boolean
descriptionHtml: string
descriptionText: string
end: string
htmlLink: string
location: string
organizerDisplayName: string
organizerEmail: string
organizerId: string
organizerSelf: boolean
recurrence: [string]
remoteId: string
sequence: number
sourceId: string
start: string
status: string
summary: string
title: string
updatedAt: string
attachments: Array<ImageBlock>
}
export namespace Explore {
interface ExploreNearObjectInpObj {
beacon?: string
certainty?: number
distance?: number
id?: string
}
interface Txt2VecC11yExploreMoveToMovementObjectsInpObj {
id?: string
beacon?: string
}
interface Txt2VecC11yExploreMoveTo {
concepts?: string[]
objects?: Txt2VecC11yExploreMoveToMovementObjectsInpObj[]
force?: number
}
interface Txt2VecC11yExploreMoveAwayFromMovementObjectsInpObj {
id?: string
beacon?: string
}
interface Txt2VecC11yExploreMoveAwayFrom {
concepts?: string[]
objects?: Txt2VecC11yExploreMoveAwayFromMovementObjectsInpObj[]
force?: number
}
interface Txt2VecC11yExploreNearTextInpObj {
moveTo?: Txt2VecC11yExploreMoveTo
certainty?: number
distance?: number
moveAwayFrom?: Txt2VecC11yExploreMoveAwayFrom
concepts?: string[]
}
interface ExploreNearVectorInpObj {
distance?: number
vector?: number[]
certainty?: number
}
interface QnATransformersExploreAskInpObj {
question: string
properties?: string[]
}
export interface ExploreArgs {
nearObject?: ExploreNearObjectInpObj
nearText?: Txt2VecC11yExploreNearTextInpObj
ask?: QnATransformersExploreAskInpObj
offset?: number
limit?: number
nearVector?: ExploreNearVectorInpObj
}
}
}

View File

@ -0,0 +1,30 @@
import { UnbodyGraphQl } from './unbody-content.types'
export type UnbodyGoogleDoc = UnbodyGraphQl.GoogleDoc
export type UnbodyGoogleCalendarEvent = UnbodyGraphQl.GoogleCalendarEvent
export type UnbodyTextBlock = UnbodyGraphQl.TextBlock
export type UnbodyImageBlock = UnbodyGraphQl.ImageBlock
export type UnbodyAudio = UnbodyGraphQl.AudioFile
export type UnbodyExploreArgs = UnbodyGraphQl.Explore.ExploreArgs
export type UnbodyGraphQlResponse<T> = {
data: {
Get: T
}
}
export type UnbodyGraphQlResponseGoogleDoc = UnbodyGraphQlResponse<{
GoogleDoc: UnbodyGoogleDoc[]
}>
export type UnbodyGraphQlResponseGoogleCalendarEvent = UnbodyGraphQlResponse<{
GoogleCalendarEvent: UnbodyGoogleCalendarEvent[]
}>
export type UnbodyGraphQlResponseTextBlock = UnbodyGraphQlResponse<{
TextBlock: UnbodyTextBlock[]
}>
export type UnbodyGraphQlResponseImageBlock = UnbodyGraphQlResponse<{
ImageBlock: UnbodyImageBlock[]
}>

View File

@ -0,0 +1,27 @@
import { UnbodyExploreArgs } from './unbody.types'
export const pareseExploreArgs = (args: UnbodyExploreArgs = {}): string => {
const parse = (obj: any): string | number => {
if (typeof obj === 'number') {
return obj
}
if (Array.isArray(obj)) {
const props = obj.map((value) => `${parse(value)}`).join(',')
return `[${props}]`
}
if (typeof obj === 'object') {
const props = Object.keys(obj)
.map((key) => `${key}:${parse(obj[key])}`)
.join(',')
return `{${props}}`
}
return JSON.stringify(obj)
}
const p = parse(args)
//remove the first and last curly braces
return typeof p === 'string' ? p.substring(1, p.length - 1) : p + ''
}

View File

@ -1,13 +1,15 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import unbody, { getHomepagePosts } from '@/services/unbody.service'
import type { NextApiRequest, NextApiResponse } from 'next'
type Data = {
name: string
}
export default function handler(
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
res: NextApiResponse<any>,
) {
res.status(200).json({ name: 'John Doe' })
try {
const data = await getHomepagePosts()
res.status(200).json(data)
} catch (e: any) {
console.log(e)
res.status(e.response.statusCode || 500).send(e.message)
}
}

View File

@ -1,9 +1,45 @@
import { PostDataProps } from '@/components/Post/Post'
import PostsDemo from '@/components/Post/PostsDemo'
import { UnbodyGoogleDoc, UnbodyImageBlock } from '@/lib/unbody/unbody.types'
import { getHomepagePosts } from '@/services/unbody.service'
import { GetStaticProps } from 'next'
export default function Home() {
type Props = {
posts: PostDataProps[]
error: string | null
}
export default function Home({ posts }: Props) {
return (
<>
<PostsDemo />
<PostsDemo posts={posts} featuredPost={posts[0]} />
</>
)
}
export const getStaticProps = async () => {
let posts: Partial<UnbodyGoogleDoc>[] = []
let error = null
try {
posts = await getHomepagePosts()
} catch (e) {
error = JSON.stringify(e)
}
return {
props: {
posts: posts.map((post) => ({
date: post.modifiedAt,
title: post.title,
description: post.summary,
author: 'Jinho',
tags: post.tags,
...(post.blocks && post.blocks!.length > 0
? { coverImage: post.blocks![0] as UnbodyImageBlock }
: {}),
})),
error,
},
}
}

25
src/queries/getPosts.ts Normal file
View File

@ -0,0 +1,25 @@
import { gql } from 'graphql-request'
import { GetGoogleDocQuery, GetQuery } from '.'
import { pareseExploreArgs } from '@/lib/unbody/unbody.utils'
import { UnbodyExploreArgs } from '@/lib/unbody/unbody.types'
const defaultArgs: UnbodyExploreArgs = {
limit: 10,
nearText: { concepts: ['home'] },
}
export const getHomePagePostsQuery = (args: UnbodyExploreArgs = defaultArgs) =>
GetGoogleDocQuery(args)(`
title
summary
tags
createdAt
modifiedAt
blocks{
...on ImageBlock{
url
alt
}
}
`)

7
src/queries/index.ts Normal file
View File

@ -0,0 +1,7 @@
import { UnbodyExploreArgs } from '@/lib/unbody/unbody.types'
import { pareseExploreArgs } from '@/lib/unbody/unbody.utils'
export const GetQuery = (q: string) => `query { Get{ ${q} } }`
export const GetGoogleDocQuery = (args: UnbodyExploreArgs) => (q: string) =>
GetQuery(`GoogleDoc(${pareseExploreArgs(args)}){ ${q} }`)

View File

@ -0,0 +1,26 @@
import { UnbodyClient } from '@/lib/unbody/client.class'
import {
UnbodyGoogleDoc,
UnbodyGraphQlResponseGoogleDoc,
} from '@/lib/unbody/unbody.types'
import { getHomePagePostsQuery } from '@/queries/getPosts'
const { UNBODY_API_KEY, UNBODY_LPE_PROJECT_ID } = process.env
const unbody = new UnbodyClient(
UNBODY_API_KEY as string,
UNBODY_LPE_PROJECT_ID as string,
)
type HomepagePost = Pick<
UnbodyGoogleDoc,
'title' | 'summary' | 'tags' | 'modifiedAt' | 'subtitle' | 'blocks'
>
export const getHomepagePosts = (): Promise<HomepagePost[]> => {
return unbody
.request<UnbodyGraphQlResponseGoogleDoc>(getHomePagePostsQuery())
.then(({ data }) => data.Get.GoogleDoc)
}
export default unbody

113
yarn.lock
View File

@ -203,6 +203,11 @@
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.38.0.tgz#73a8a0d8aa8a8e6fe270431c5e72ae91b5337892"
integrity sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g==
"@graphql-typed-document-node/core@^3.2.0":
version "3.2.0"
resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861"
integrity sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==
"@hookstate/core@^4.0.1":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@hookstate/core/-/core-4.0.1.tgz#6744380e96ce13fe3488c926c1cbae93bbea0ff6"
@ -578,6 +583,11 @@ astral-regex@^2.0.0:
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
available-typed-arrays@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7"
@ -588,6 +598,15 @@ axe-core@^4.6.2:
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.6.3.tgz#fc0db6fdb65cc7a80ccf85286d91d64ababa3ece"
integrity sha512-/BQzOX780JhsxDnPpH4ZiyrJAzcd8AfzFPkv+89veFSr1rcMjuq2JDCwypKaPeB6ljHp9KjXhPpjgCvQlWYuqg==
axios@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f"
integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==
dependencies:
follow-redirects "^1.15.0"
form-data "^4.0.0"
proxy-from-env "^1.1.0"
axobject-query@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.1.1.tgz#3b6e5c6d4e43ca7ba51c5babf99d22a9c68485e1"
@ -645,9 +664,9 @@ callsites@^3.0.0:
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
caniuse-lite@^1.0.30001406:
version "1.0.30001478"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001478.tgz#0ef8a1cf8b16be47a0f9fc4ecfc952232724b32a"
integrity sha512-gMhDyXGItTHipJj2ApIvR+iVB5hd0KP3svMWWXDvZOmjzJJassGLMfxRkQCSYgGd2gtdL/ReeiyvMSFD1Ss6Mw==
version "1.0.30001482"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001482.tgz#8b3fad73dc35b2674a5c96df2d4f9f1c561435de"
integrity sha512-F1ZInsg53cegyjroxLNW9DmrEQ1SuGRTO1QlpA0o2/6OpQ0gFeDRoq1yFmnr8Sakn9qwwt9DmbxHB6w167OSuQ==
chalk@5.2.0:
version "5.2.0"
@ -738,6 +757,13 @@ colorette@^2.0.19:
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a"
integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
commander@^10.0.0:
version "10.0.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06"
@ -771,6 +797,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"
@ -860,6 +893,11 @@ define-properties@^1.1.3, define-properties@^1.1.4:
has-property-descriptors "^1.0.0"
object-keys "^1.1.1"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
dir-glob@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
@ -1317,6 +1355,11 @@ flatted@^3.1.0:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787"
integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
follow-redirects@^1.15.0:
version "1.15.2"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
for-each@^0.3.3:
version "0.3.3"
resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e"
@ -1324,6 +1367,15 @@ for-each@^0.3.3:
dependencies:
is-callable "^1.1.3"
form-data@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
mime-types "^2.1.12"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@ -1478,6 +1530,19 @@ grapheme-splitter@^1.0.4:
resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e"
integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==
graphql-request@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-6.0.0.tgz#9c8b6a0c341f289e049936d03cc9205300faae1c"
integrity sha512-2BmHTuglonjZvmNVw6ZzCfFlW/qkIPds0f+Qdi/Lvjsl3whJg2uvHmSvHnLWhUTEw6zcxPYAHiZoPvSVKOZ7Jw==
dependencies:
"@graphql-typed-document-node/core" "^3.2.0"
cross-fetch "^3.1.5"
graphql@^16.6.0:
version "16.6.0"
resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.6.0.tgz#c2dcffa4649db149f6282af726c8c83f1c7c5fdb"
integrity sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw==
has-bigints@^1.0.1, has-bigints@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa"
@ -1975,6 +2040,18 @@ micromatch@^4.0.4, micromatch@^4.0.5:
braces "^3.0.2"
picomatch "^2.3.1"
mime-db@1.52.0:
version "1.52.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-types@^2.1.12:
version "2.1.35"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"
mimic-fn@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
@ -2053,6 +2130,13 @@ next@13.3.0:
"@next/swc-win32-ia32-msvc" "13.3.0"
"@next/swc-win32-x64-msvc" "13.3.0"
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"
normalize-path@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
@ -2286,6 +2370,11 @@ 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==
punycode@^2.1.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f"
@ -2781,6 +2870,11 @@ toggle-selection@^1.0.6:
resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32"
integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==
tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
ts-easing@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/ts-easing/-/ts-easing-0.2.0.tgz#c8a8a35025105566588d87dbda05dd7fbfa5a4ec"
@ -2866,6 +2960,19 @@ use-sync-external-store@^1.2.0:
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
whatwg-url@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
dependencies:
tr46 "~0.0.3"
webidl-conversions "^3.0.0"
which-boxed-primitive@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"