mirror of
https://github.com/koreanbots/core.git
synced 2025-12-16 14:30:22 +00:00
Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1639f9b8a3 | ||
|
|
cc9327d3cc | ||
|
|
1325a1212e | ||
|
|
1e975586f8 | ||
|
|
925b0bd98e | ||
|
|
3d0300806a | ||
|
|
5c1b8852d8 | ||
|
|
7a1a2d6828 | ||
|
|
51aa8e39e7 | ||
|
|
8a96148245 | ||
|
|
218e7909b3 | ||
|
|
843e4137cb | ||
|
|
9aaf66018f | ||
|
|
a2adbf116e | ||
|
|
3af7bd3079 | ||
|
|
74ffad6a18 | ||
|
|
ce4daba865 | ||
|
|
54fa52edbf | ||
|
|
14598019e8 | ||
|
|
e3e407af67 | ||
|
|
486481d5d0 | ||
|
|
6fad2e1369 | ||
|
|
7fb55148f2 | ||
|
|
8e7e14ba80 | ||
|
|
57ad6b5fa7 | ||
|
|
8c6043f013 | ||
|
|
646b35e849 | ||
|
|
c49085b0f2 | ||
|
|
bb7e283218 | ||
|
|
5132c2243a | ||
|
|
5382fd334b | ||
|
|
8b13d9a9a5 | ||
|
|
94c8f769aa | ||
|
|
957fc672ce | ||
|
|
f7a17ba8ce | ||
|
|
06113a943e | ||
|
|
4416cb58b3 | ||
|
|
8ab5e433d2 | ||
|
|
6e37411764 | ||
|
|
efdc10ea25 | ||
| b7ca0cfc03 |
@ -1,4 +1,5 @@
|
||||
KOREANBOTS_URL=http://localhost:3000
|
||||
MYSQL_PORT=3306
|
||||
MYSQL_HOST=mysql
|
||||
MYSQL_USER=root
|
||||
MYSQL_PASSWORD=YOUSHALLNOTPASS
|
||||
@ -33,3 +34,4 @@ REVIEW_LOG_WEBHOOK_URL=
|
||||
OPEN_REVIEW_LOG_WEBHOOK_URL=
|
||||
STATS_LOG_WEBHOOK_URL=
|
||||
REPORT_WEBHOOK_URL=
|
||||
NOTICE_LOG_WEBHOOK_URL=
|
||||
|
||||
@ -18,7 +18,8 @@ const BotCard: React.FC<BotCardProps> = ({ manage = false, bot }) => {
|
||||
<div
|
||||
className='relative mx-auto h-full rounded-2xl bg-little-white text-black shadow-xl dark:bg-discord-black dark:text-white'
|
||||
style={
|
||||
checkBotFlag(bot.flags, 'trusted') && bot.banner
|
||||
(checkBotFlag(bot.flags, 'trusted') || checkBotFlag(bot.flags, 'partnered')) &&
|
||||
bot.banner
|
||||
? {
|
||||
background: `linear-gradient(to right, rgba(34, 36, 38, 0.68), rgba(34, 36, 38, 0.68)), url("${bot.banner}") center top / cover no-repeat`,
|
||||
color: 'white',
|
||||
|
||||
@ -21,7 +21,7 @@ const Label: React.FC<LabelProps> = ({
|
||||
<span className='align-text-top text-base font-semibold text-red-500'> *</span>
|
||||
)}
|
||||
</h3>
|
||||
{labelDesc}
|
||||
<span className='whitespace-pre-line'>{labelDesc}</span>
|
||||
</div>
|
||||
)}
|
||||
<div className={short ? 'col-span-1' : 'col-span-3'}>
|
||||
|
||||
@ -109,7 +109,10 @@ const Select: React.FC<SelectProps> = ({
|
||||
onChange={handleChange}
|
||||
onBlur={handleTouch}
|
||||
noOptionsMessage={() => '검색 결과가 없습니다.'}
|
||||
value={values.map((el) => ({ label: el, value: el }))}
|
||||
value={values.map((el) => ({
|
||||
label: Object.values(options).find(({ value }) => value === el)?.label || el,
|
||||
value: el,
|
||||
}))}
|
||||
components={{
|
||||
MultiValue,
|
||||
MultiValueRemove,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import dynamic from 'next/dynamic'
|
||||
import { NextSeo } from 'next-seo'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { useState } from 'react'
|
||||
|
||||
import {
|
||||
botCategories,
|
||||
@ -13,6 +14,7 @@ const Tag = dynamic(() => import('@components/Tag'))
|
||||
const Search = dynamic(() => import('@components/Search'))
|
||||
|
||||
const Hero: React.FC<HeroProps> = ({ type = 'all', header, description }) => {
|
||||
const [showAllCategories, setShowAllCategories] = useState(false)
|
||||
const link = `/${type}/categories`
|
||||
return (
|
||||
<>
|
||||
@ -27,7 +29,8 @@ const Hero: React.FC<HeroProps> = ({ type = 'all', header, description }) => {
|
||||
<div className='mb-8 bg-discord-blurple text-gray-100 dark:bg-discord-black md:p-0'>
|
||||
<Container className='pb-16 pt-24 md:pb-20' ignoreColor>
|
||||
<h1 className='hidden text-left text-3xl font-bold md:block'>
|
||||
{header && `${header} - `}한국 디스코드 리스트
|
||||
{header && `${header} - `} {{ bots: '봇 | ', servers: '서버 | ' }[type] || ''}
|
||||
한국 디스코드 리스트
|
||||
</h1>
|
||||
<h1 className='text-center text-3xl font-semibold md:hidden'>
|
||||
{header && (
|
||||
@ -36,7 +39,7 @@ const Hero: React.FC<HeroProps> = ({ type = 'all', header, description }) => {
|
||||
<br />
|
||||
</span>
|
||||
)}
|
||||
한국 디스코드 리스트
|
||||
{{ bots: '봇 | ', servers: '서버 | ' }[type] || ''}한국 디스코드 리스트
|
||||
</h1>
|
||||
<p className='font-base mt-2 text-center text-xl sm:text-left'>
|
||||
{description ||
|
||||
@ -109,7 +112,9 @@ const Hero: React.FC<HeroProps> = ({ type = 'all', header, description }) => {
|
||||
bigger
|
||||
href={type === 'bots' ? '/bots/list/votes' : '/servers/list/votes'}
|
||||
/>
|
||||
{(type === 'bots' ? botCategories : serverCategories).slice(0, 4).map((t) => (
|
||||
{(type === 'bots' ? botCategories : serverCategories)
|
||||
.slice(0, showAllCategories ? undefined : 4)
|
||||
.map((t) => (
|
||||
<Tag
|
||||
key={t}
|
||||
text={
|
||||
@ -127,14 +132,16 @@ const Hero: React.FC<HeroProps> = ({ type = 'all', header, description }) => {
|
||||
))}
|
||||
<Tag
|
||||
key='tag'
|
||||
className='cursor-pointer'
|
||||
text={
|
||||
<>
|
||||
<i className='fas fa-tag' /> 카테고리 더보기
|
||||
<i className='fas fa-tag' />{' '}
|
||||
{showAllCategories ? '간략히 보기' : '카테고리 더보기'}
|
||||
</>
|
||||
}
|
||||
dark
|
||||
bigger
|
||||
href={link}
|
||||
onClick={() => setShowAllCategories(!showAllCategories)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
@ -1,14 +1,16 @@
|
||||
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
||||
/* eslint-disable jsx-a11y/no-noninteractive-tabindex */
|
||||
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
||||
import { useEffect, useState } from 'react'
|
||||
import Link from 'next/link'
|
||||
import dynamic from 'next/dynamic'
|
||||
import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import Logo from 'public/logo-transparent.png'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { redirectTo } from '@utils/Tools'
|
||||
import Fetch from '@utils/Fetch'
|
||||
import { Nullable, User, UserCache } from '@types'
|
||||
import Fetch from '@utils/Fetch'
|
||||
import { redirectTo } from '@utils/Tools'
|
||||
|
||||
const DiscordAvatar = dynamic(() => import('@components/DiscordAvatar'))
|
||||
|
||||
@ -49,9 +51,16 @@ const Navbar: React.FC<NavbarProps> = ({ token }) => {
|
||||
setUserCache(null)
|
||||
}
|
||||
}, [token])
|
||||
|
||||
return (
|
||||
<>
|
||||
<nav className='fixed top-0 z-40 flex w-full flex-wrap items-center justify-between bg-discord-blurple px-2 py-3 text-gray-100 dark:bg-discord-black lg:absolute'>
|
||||
<div className='fixed left-0 right-0 top-0 z-50'>
|
||||
<nav
|
||||
className={`fixed top-0 z-40 flex w-full flex-wrap items-center justify-between px-2 py-2 text-gray-100 backdrop-blur-sm transition-colors duration-300 ${
|
||||
dev
|
||||
? 'bg-discord-blurple dark:bg-discord-black'
|
||||
: 'bg-discord-blurple/90 dark:bg-discord-black/30'
|
||||
} lg:absolute`}
|
||||
>
|
||||
<div className='container mx-auto flex flex-wrap items-center justify-between px-4'>
|
||||
<div className='relative flex w-full justify-between lg:w-auto lg:justify-start'>
|
||||
<Link
|
||||
@ -65,7 +74,7 @@ const Navbar: React.FC<NavbarProps> = ({ token }) => {
|
||||
<i className='fas fa-tools mr-1' /> DEVELOPERS
|
||||
</>
|
||||
) : (
|
||||
'KOREANLIST'
|
||||
<Image src={Logo} alt='Koreanbots' width={100} height={100} className='h-10 w-10' />
|
||||
)}
|
||||
</Link>
|
||||
<button
|
||||
@ -160,7 +169,7 @@ const Navbar: React.FC<NavbarProps> = ({ token }) => {
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className='hidden grow items-center bg-white lg:flex lg:bg-transparent lg:shadow-none'>
|
||||
<div className='hidden lg:flex lg:items-center lg:bg-transparent lg:shadow-none'>
|
||||
<ul className='flex list-none flex-col lg:ml-auto lg:flex-row'>
|
||||
<li
|
||||
className='flex items-center outline-none'
|
||||
@ -368,7 +377,7 @@ const Navbar: React.FC<NavbarProps> = ({ token }) => {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import Link from 'next/link'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { makeBotURL, makeServerURL, redirectTo } from '@utils/Tools'
|
||||
import { Bot, ResponseProps, Server } from '@types'
|
||||
import Fetch from '@utils/Fetch'
|
||||
import { Bot, Server, ResponseProps } from '@types'
|
||||
import { makeBotURL, makeServerURL, redirectTo } from '@utils/Tools'
|
||||
import dynamic from 'next/dynamic'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
|
||||
import Day from '@utils/Day'
|
||||
import useOutsideClick from '@utils/useOutsideClick'
|
||||
@ -12,7 +12,11 @@ import useOutsideClick from '@utils/useOutsideClick'
|
||||
const DiscordAvatar = dynamic(() => import('@components/DiscordAvatar'))
|
||||
const ServerIcon = dynamic(() => import('@components/ServerIcon'))
|
||||
|
||||
const Search: React.FC = () => {
|
||||
interface SearchProps {
|
||||
compact?: boolean
|
||||
}
|
||||
|
||||
const Search: React.FC<SearchProps> = ({ compact = false }) => {
|
||||
const router = useRouter()
|
||||
const ref = useRef()
|
||||
const [query, setQuery] = useState('')
|
||||
@ -101,12 +105,13 @@ const Search: React.FC = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`relative w-full z-10 ${compact ? '' : 'mt-5'}`}>
|
||||
<div onFocus={() => setHidden(false)} ref={ref}>
|
||||
<div className='relative z-10 mt-5 flex w-full rounded-lg bg-white text-black dark:bg-very-black dark:text-gray-100'>
|
||||
<div className={`relative z-10 flex w-full items-center bg-white text-black dark:bg-very-black dark:text-gray-100 ${compact ? 'h-10 px-3 rounded-md' : 'rounded-lg'}`}>
|
||||
<input
|
||||
type='search'
|
||||
maxLength={50}
|
||||
className='h-16 grow border-0 border-none bg-transparent px-7 py-3 pr-20 text-xl shadow outline-none'
|
||||
className={`grow border-0 border-none bg-transparent pr-20 shadow outline-none ${compact ? 'h-10 text-sm' : 'h-16 px-7 py-3 text-xl'}`}
|
||||
placeholder='검색...'
|
||||
value={query}
|
||||
onChange={(e) => {
|
||||
@ -119,14 +124,14 @@ const Search: React.FC = () => {
|
||||
}}
|
||||
/>
|
||||
<button
|
||||
className='cusor-pointer absolute right-0 top-0 mr-5 mt-5 outline-none'
|
||||
className='absolute right-4 top-1/2 -translate-y-1/2 outline-none'
|
||||
onClick={onSubmit}
|
||||
>
|
||||
<i className='fas fa-search text-2xl text-gray-600 hover:text-gray-700' />
|
||||
<i className={`fas fa-search text-gray-600 hover:text-gray-700 ${compact ? 'text-sm' : 'text-2xl'}`} />
|
||||
</button>
|
||||
</div>
|
||||
<div className={`relative ${hidden ? 'hidden' : 'block'} z-50`}>
|
||||
<div className='pin-t pin-l absolute my-2 h-60 w-full overflow-y-scroll rounded bg-white text-black shadow-md dark:bg-very-black dark:text-gray-100 md:h-80'>
|
||||
<div className='absolute top-full mt-2 max-h-60 w-full overflow-y-auto rounded bg-white text-black shadow-md dark:bg-very-black dark:text-gray-100 md:h-80'>
|
||||
<ul>
|
||||
{data && data.code === 200 ? (
|
||||
<div className='grid lg:grid-cols-2'>
|
||||
@ -172,7 +177,7 @@ const Search: React.FC = () => {
|
||||
<li className='px-3 py-3.5'>검색중입니다...</li>
|
||||
</ul>
|
||||
) : (
|
||||
<ul>
|
||||
<ul className='px-3 py-3.5'>
|
||||
{query && data ? (
|
||||
data.message?.includes('문법') ? (
|
||||
<li className='px-3 py-3.5'>
|
||||
@ -194,10 +199,10 @@ const Search: React.FC = () => {
|
||||
)
|
||||
) : query.length === 0 ? (
|
||||
!recentSearch || !Array.isArray(recentSearch) || recentSearch.length === 0 ? (
|
||||
<li className='px-3 py-3.5'>최근 검색 기록이 없습니다.</li>
|
||||
<li >최근 검색 기록이 없습니다.</li>
|
||||
) : (
|
||||
<>
|
||||
<li className='h-15 cursor-pointer px-3 py-2 font-semibold'>
|
||||
<li className='h-15 cursor-pointer font-semibold'>
|
||||
최근 검색어
|
||||
<button
|
||||
className='absolute right-0 pr-10 text-sm text-red-500 hover:opacity-90'
|
||||
@ -236,6 +241,7 @@ const Search: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -27,7 +27,9 @@ const ServerCard: React.FC<BotCardProps> = ({ type, server }) => {
|
||||
<div
|
||||
className='relative mx-auto h-full rounded-2xl bg-little-white text-black shadow-xl dark:bg-discord-black dark:text-white'
|
||||
style={
|
||||
checkServerFlag(server.flags, 'trusted') && server.banner
|
||||
(checkServerFlag(server.flags, 'trusted') ||
|
||||
checkServerFlag(server.flags, 'partnered')) &&
|
||||
server.banner
|
||||
? {
|
||||
background: `linear-gradient(to right, rgba(34, 36, 38, 0.68), rgba(34, 36, 38, 0.68)), url("${server.banner}") center top / cover no-repeat`,
|
||||
color: 'white',
|
||||
|
||||
@ -7,5 +7,6 @@ export async function register() {
|
||||
version: packageJson.version,
|
||||
env: process.env.DD_ENV,
|
||||
})
|
||||
tracer.use('next')
|
||||
}
|
||||
}
|
||||
|
||||
12
package.json
12
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "koreanbots",
|
||||
"version": "2.9.2",
|
||||
"version": "2.12.2",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
@ -28,11 +28,10 @@
|
||||
"csrf": "3.1.0",
|
||||
"dataloader": "2.2.2",
|
||||
"dayjs": "^1.11.9",
|
||||
"dd-trace": "^5.30.0",
|
||||
"dd-trace": "5.24.0",
|
||||
"difflib": "0.2.4",
|
||||
"discord.js": "^14.12.1",
|
||||
"emoji-mart": "3.0.1",
|
||||
"erlpack": "0.1.4",
|
||||
"express-rate-limit": "^5.3.0",
|
||||
"firebase": "^11.2.0",
|
||||
"firebase-admin": "^13.0.2",
|
||||
@ -41,9 +40,9 @@
|
||||
"josa": "3.0.1",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"knex": "^2.4.0",
|
||||
"mongoose": "6.13.5",
|
||||
"mongoose": "6.13.6",
|
||||
"mysql": "2.18.1",
|
||||
"next": "^14.2.22",
|
||||
"next": "^14.2.32",
|
||||
"next-connect": "0.10.1",
|
||||
"next-pwa": "^5.6.0",
|
||||
"next-seo": "^6.1.0",
|
||||
@ -101,5 +100,6 @@
|
||||
"resolutions": {
|
||||
"@types/react": "^17.0.15"
|
||||
},
|
||||
"license": "AGPL-3.0"
|
||||
"license": "AGPL-3.0",
|
||||
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
||||
}
|
||||
|
||||
@ -1,28 +1,28 @@
|
||||
import Head from 'next/head'
|
||||
import { DefaultSeo } from 'next-seo'
|
||||
import App, { AppContext, AppProps } from 'next/app'
|
||||
import dynamic from 'next/dynamic'
|
||||
import Head from 'next/head'
|
||||
import { Router, useRouter } from 'next/router'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { DefaultSeo } from 'next-seo'
|
||||
import { GlobalHotKeys } from 'react-hotkeys'
|
||||
import NProgress from 'nprogress'
|
||||
import Package from '../package.json'
|
||||
import { useEffect, useState } from 'react'
|
||||
import ReactGA from 'react-ga'
|
||||
import { GlobalHotKeys } from 'react-hotkeys'
|
||||
import Package from '../package.json'
|
||||
|
||||
import { Theme } from '@types'
|
||||
import { DESCRIPTION, shortcutKeyMap, THEME_COLOR, TITLE } from '@utils/Constants'
|
||||
import Logger from '@utils/Logger'
|
||||
import { handlePWA, parseCookie, parseDockerhubTag, systemTheme } from '@utils/Tools'
|
||||
import { DESCRIPTION, shortcutKeyMap, THEME_COLOR, TITLE } from '@utils/Constants'
|
||||
import { Theme } from '@types'
|
||||
|
||||
const Footer = dynamic(() => import('@components/Footer'))
|
||||
const Navbar = dynamic(() => import('@components/Navbar'))
|
||||
const Modal = dynamic(() => import('@components/Modal'))
|
||||
|
||||
import PlatformDisplay from '@components/PlatformDisplay'
|
||||
import '@fortawesome/fontawesome-free/css/all.css'
|
||||
import 'rc-tooltip/assets/bootstrap_white.css'
|
||||
import '../app.css'
|
||||
import '../github-markdown.css'
|
||||
import 'rc-tooltip/assets/bootstrap_white.css'
|
||||
import '@fortawesome/fontawesome-free/css/all.css'
|
||||
import PlatformDisplay from '@components/PlatformDisplay'
|
||||
|
||||
// Progress Bar
|
||||
NProgress.configure({ showSpinner: false })
|
||||
|
||||
@ -10,7 +10,7 @@ import HCaptcha from '@hcaptcha/react-hcaptcha'
|
||||
import { get } from '@utils/Query'
|
||||
import { cleanObject, parseCookie, redirectTo } from '@utils/Tools'
|
||||
import { AddBotSubmit, AddBotSubmitSchema } from '@utils/Yup'
|
||||
import { botCategories, botCategoryDescription, library } from '@utils/Constants'
|
||||
import { botCategories, botCategoryDescription, botEnforcements, library } from '@utils/Constants'
|
||||
import { getToken } from '@utils/Csrf'
|
||||
import Fetch from '@utils/Fetch'
|
||||
import { ResponseProps, SubmittedBot, Theme, User } from '@types'
|
||||
@ -57,6 +57,7 @@ const AddBot: NextPage<AddBotProps> = ({ logged, user, csrfToken, theme }) => {
|
||||
- 어떤
|
||||
- 기능
|
||||
- 있나요?`,
|
||||
enforcements: [],
|
||||
_csrf: csrfToken,
|
||||
_captcha: 'captcha',
|
||||
}
|
||||
@ -175,6 +176,18 @@ const AddBot: NextPage<AddBotProps> = ({ logged, user, csrfToken, theme }) => {
|
||||
있습니다.
|
||||
</li>
|
||||
<li>또한, 봇을 등록하게 되면 작성하신 모든 정보는 웹과 API에 공개됩니다.</li>
|
||||
<li>
|
||||
봇 심사에 대한 자세한 내용은{' '}
|
||||
<Link
|
||||
href='https://contents.koreanbots.dev/bot-review'
|
||||
rel='noreferrer'
|
||||
target='_blank'
|
||||
className='text-blue-500 hover:text-blue-600'
|
||||
>
|
||||
봇 심사 가이드
|
||||
</Link>
|
||||
를 참고해주세요.
|
||||
</li>
|
||||
</ul>
|
||||
</Message>
|
||||
</div>
|
||||
@ -186,8 +199,8 @@ const AddBot: NextPage<AddBotProps> = ({ logged, user, csrfToken, theme }) => {
|
||||
<div className='flex items-center'>
|
||||
<CheckBox name='agree' />
|
||||
<strong className='ml-2 text-sm'>
|
||||
해당 내용을 숙지하였으며, 모두 이행하였고 위 내용에 해당하는 거부 사유는 답변받지
|
||||
않는다는 점을 이해합니다.
|
||||
위 내용을 모두 숙지하였으며, 이행하지 않은 경우 심사가 거부될 수 있다는 것을
|
||||
이해합니다.
|
||||
</strong>
|
||||
</div>
|
||||
</Label>
|
||||
@ -356,6 +369,44 @@ const AddBot: NextPage<AddBotProps> = ({ logged, user, csrfToken, theme }) => {
|
||||
</Segment>
|
||||
</Label>
|
||||
<Divider />
|
||||
<Label
|
||||
For='enforcements'
|
||||
label='필수 고지 내용'
|
||||
labelDesc='내용에 해당하는 경우 필수로 선택해야 합니다.'
|
||||
required
|
||||
error={
|
||||
errors.enforcements && touched.enforcements ? (errors.enforcements as string) : null
|
||||
}
|
||||
>
|
||||
<Selects
|
||||
options={Object.entries(botEnforcements)
|
||||
.filter(([k]) => k === 'NONE' || !values.enforcements.includes('NONE'))
|
||||
.map(([k, v]) => ({
|
||||
label: v.label,
|
||||
value: k,
|
||||
}))}
|
||||
handleChange={(values) => {
|
||||
if (values.some((i) => i.value === 'NONE')) {
|
||||
setFieldValue('enforcements', ['NONE'])
|
||||
} else {
|
||||
setFieldValue(
|
||||
'enforcements',
|
||||
values.map((v) => v.value)
|
||||
)
|
||||
}
|
||||
}}
|
||||
handleTouch={() => setFieldTouched('enforcements', true)}
|
||||
values={values.enforcements ?? ([] as string[])}
|
||||
setValues={(values) => {
|
||||
if (values.includes('NONE')) {
|
||||
setFieldValue('enforcements', ['NONE'])
|
||||
} else {
|
||||
setFieldValue('enforcements', values)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Label>
|
||||
<Divider />
|
||||
<p className='mb-5 mt-2 text-base'>
|
||||
<span className='font-semibold text-red-500'> *</span> = 필수 항목
|
||||
</p>
|
||||
|
||||
@ -10,12 +10,13 @@ import {
|
||||
AddBotSubmit,
|
||||
AddBotSubmitSchema,
|
||||
CsrfCaptcha,
|
||||
getManageBotSchema,
|
||||
ManageBot,
|
||||
ManageBotSchema,
|
||||
} from '@utils/Yup'
|
||||
import RequestHandler from '@utils/RequestHandler'
|
||||
import { User } from '@types'
|
||||
import {
|
||||
checkBotFlag,
|
||||
checkUserFlag,
|
||||
diff,
|
||||
inspect,
|
||||
@ -25,7 +26,6 @@ import {
|
||||
} from '@utils/Tools'
|
||||
import { discordLog, getMainGuild, webhookClients } from '@utils/DiscordBot'
|
||||
import { KoreanbotsEndPoints } from '@utils/Constants'
|
||||
import { userInfo } from 'os'
|
||||
|
||||
const patchLimiter = rateLimit({
|
||||
windowMs: 2 * 60 * 1000,
|
||||
@ -39,6 +39,10 @@ const patchLimiter = rateLimit({
|
||||
})
|
||||
const Bots = RequestHandler()
|
||||
.get(async (req: GetApiRequest, res) => {
|
||||
const auth = req.headers.authorization
|
||||
? await get.BotAuthorization(req.headers.authorization)
|
||||
: await get.Authorization(req.cookies.token)
|
||||
if (!auth) return ResponseWrapper(res, { code: 401 })
|
||||
const bot = await get.bot.load(req.query.id)
|
||||
if (!bot) return ResponseWrapper(res, { code: 404, message: '존재하지 않는 봇입니다.' })
|
||||
else {
|
||||
@ -128,7 +132,11 @@ const Bots = RequestHandler()
|
||||
: `${userinfo.username}#${userinfo.tag}`,
|
||||
iconURL:
|
||||
KoreanbotsEndPoints.URL.root +
|
||||
KoreanbotsEndPoints.CDN.avatar(userinfo.id, { format: 'png', size: 256, hash: userinfo.avatar }),
|
||||
KoreanbotsEndPoints.CDN.avatar(userinfo.id, {
|
||||
format: 'png',
|
||||
size: 256,
|
||||
hash: userinfo.avatar,
|
||||
}),
|
||||
url: KoreanbotsEndPoints.URL.user(userinfo.id),
|
||||
})
|
||||
.setTitle('대기 중')
|
||||
@ -193,6 +201,10 @@ const Bots = RequestHandler()
|
||||
if (!bot) return ResponseWrapper(res, { code: 404, message: '존재하지 않는 봇입니다.' })
|
||||
const user = await get.Authorization(req.cookies.token)
|
||||
if (!user) return ResponseWrapper(res, { code: 401 })
|
||||
|
||||
const isPerkAvailable =
|
||||
checkBotFlag(bot.flags, 'partnered') || checkBotFlag(bot.flags, 'trusted')
|
||||
|
||||
const userInfo = await get.user.load(user)
|
||||
if (
|
||||
['reported', 'blocked', 'archived'].includes(bot.state) &&
|
||||
@ -211,7 +223,8 @@ const Bots = RequestHandler()
|
||||
const csrfValidated = checkToken(req, res, req.body._csrf)
|
||||
if (!csrfValidated) return
|
||||
|
||||
const validated = await ManageBotSchema.validate(req.body, { abortEarly: false })
|
||||
const validated: ManageBot = await getManageBotSchema(isPerkAvailable)
|
||||
.validate(req.body, { abortEarly: false })
|
||||
.then((el) => el)
|
||||
.catch((e) => {
|
||||
ResponseWrapper(res, { code: 400, errors: e.errors })
|
||||
@ -219,11 +232,49 @@ const Bots = RequestHandler()
|
||||
})
|
||||
|
||||
if (!validated) return
|
||||
|
||||
if (!isPerkAvailable && (validated.vanity || validated.banner || validated.bg))
|
||||
return ResponseWrapper(res, {
|
||||
code: 403,
|
||||
message: '해당 봇은 특전을 이용할 권한이 없습니다.',
|
||||
})
|
||||
if (validated.vanity) {
|
||||
const vanity = await get.bot.load(validated.vanity)
|
||||
if (vanity && vanity.id !== bot.id) {
|
||||
return ResponseWrapper(res, {
|
||||
code: 403,
|
||||
message: '이미 사용중인 한디리 커스텀 URL 입니다.',
|
||||
errors: ['다른 커스텀 URL로 다시 시도해주세요.'],
|
||||
})
|
||||
}
|
||||
if (validated.vanity !== bot.vanity) {
|
||||
await webhookClients.internal.noticeLog.send({
|
||||
embeds: [
|
||||
{
|
||||
title: '한디리 커스텀 URL 변경',
|
||||
description: `봇: ${bot.name} - <@${bot.id}> ([${
|
||||
bot.id
|
||||
}](${KoreanbotsEndPoints.URL.bot(bot.id)}))`,
|
||||
fields: [
|
||||
{
|
||||
name: '이전',
|
||||
value: bot.vanity || '없음',
|
||||
},
|
||||
{
|
||||
name: '이후',
|
||||
value: validated.vanity || '없음',
|
||||
},
|
||||
],
|
||||
color: Colors.Blue,
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
}
|
||||
const result = await update.bot(req.query.id, validated)
|
||||
if (result === 0) return ResponseWrapper(res, { code: 400 })
|
||||
else {
|
||||
get.bot.clear(req.query.id)
|
||||
get.bot.clear(bot.vanity)
|
||||
const embed = new EmbedBuilder().setDescription(
|
||||
`${bot.name} - <@${bot.id}> ([${bot.id}](${KoreanbotsEndPoints.URL.bot(bot.id)}))`
|
||||
)
|
||||
@ -237,6 +288,10 @@ const Bots = RequestHandler()
|
||||
discord: bot.discord,
|
||||
intro: bot.intro,
|
||||
category: JSON.stringify(bot.category),
|
||||
vanity: bot.vanity,
|
||||
banner: bot.banner,
|
||||
enforcements: JSON.stringify(bot.enforcements),
|
||||
bg: bot.bg,
|
||||
},
|
||||
{
|
||||
prefix: validated.prefix,
|
||||
@ -247,6 +302,10 @@ const Bots = RequestHandler()
|
||||
discord: validated.discord,
|
||||
intro: validated.intro,
|
||||
category: JSON.stringify(validated.category),
|
||||
vanity: validated.vanity,
|
||||
banner: validated.banner,
|
||||
enforcements: JSON.stringify(validated.enforcements),
|
||||
bg: validated.bg,
|
||||
}
|
||||
)
|
||||
diffData.forEach((d) => {
|
||||
|
||||
@ -4,7 +4,11 @@ import ResponseWrapper from '@utils/ResponseWrapper'
|
||||
|
||||
import { Bot, List } from '@types'
|
||||
|
||||
const NewList = RequestHandler().get(async (_req, res) => {
|
||||
const NewList = RequestHandler().get(async (req, res) => {
|
||||
const auth = req.headers.authorization
|
||||
? await get.BotAuthorization(req.headers.authorization)
|
||||
: await get.Authorization(req.cookies.token)
|
||||
if (!auth) return ResponseWrapper(res, { code: 401 })
|
||||
const result = await get.list.new.load(1)
|
||||
return ResponseWrapper<List<Bot>>(res, { code: 200, data: result })
|
||||
})
|
||||
|
||||
@ -6,6 +6,10 @@ import { Bot, List } from '@types'
|
||||
import Yup from '@utils/Yup'
|
||||
|
||||
const VotesList = RequestHandler().get(async (req, res) => {
|
||||
const auth = req.headers.authorization
|
||||
? await get.BotAuthorization(req.headers.authorization)
|
||||
: await get.Authorization(req.cookies.token)
|
||||
if (!auth) return ResponseWrapper(res, { code: 401 })
|
||||
const page = await Yup.number()
|
||||
.positive()
|
||||
.integer()
|
||||
|
||||
@ -8,6 +8,10 @@ import { SearchQuerySchema } from '@utils/Yup'
|
||||
import { Bot, Server, List } from '@types'
|
||||
|
||||
const Search = RequestHandler().get(async (req: ApiRequest, res) => {
|
||||
const auth = req.headers.authorization
|
||||
? await get.BotAuthorization(req.headers.authorization)
|
||||
: await get.Authorization(req.cookies.token)
|
||||
if (!auth) return ResponseWrapper(res, { code: 401 })
|
||||
const validated = await SearchQuerySchema.validate({ q: req.query.q || req.query.query, page: 1 })
|
||||
.then((el) => el)
|
||||
.catch((e) => {
|
||||
|
||||
@ -8,6 +8,10 @@ import { SearchQuerySchema } from '@utils/Yup'
|
||||
import { Bot, List } from '@types'
|
||||
|
||||
const SearchBots = RequestHandler().get(async (req: ApiRequest, res: NextApiResponse) => {
|
||||
const auth = req.headers.authorization
|
||||
? await get.BotAuthorization(req.headers.authorization)
|
||||
: await get.Authorization(req.cookies.token)
|
||||
if (!auth) return ResponseWrapper(res, { code: 401 })
|
||||
const validated = await SearchQuerySchema.validate({
|
||||
q: req.query.q || req.query.query,
|
||||
page: req.query.page,
|
||||
|
||||
@ -8,6 +8,10 @@ import { SearchQuerySchema } from '@utils/Yup'
|
||||
import { Server, List } from '@types'
|
||||
|
||||
const SearchServers = RequestHandler().get(async (req: ApiRequest, res: NextApiResponse) => {
|
||||
const auth = req.headers.authorization
|
||||
? await get.BotAuthorization(req.headers.authorization)
|
||||
: await get.Authorization(req.cookies.token)
|
||||
if (!auth) return ResponseWrapper(res, { code: 401 })
|
||||
const validated = await SearchQuerySchema.validate({
|
||||
q: req.query.q || req.query.query,
|
||||
page: req.query.page,
|
||||
|
||||
@ -36,6 +36,10 @@ const patchLimiter = rateLimit({
|
||||
})
|
||||
const Servers = RequestHandler()
|
||||
.get(async (req: GetApiRequest, res) => {
|
||||
const auth = req.headers.authorization
|
||||
? await get.BotAuthorization(req.headers.authorization)
|
||||
: await get.Authorization(req.cookies.token)
|
||||
if (!auth) return ResponseWrapper(res, { code: 401 })
|
||||
const server = await get.server.load(req.query.id)
|
||||
if (!server) return ResponseWrapper(res, { code: 404, message: '존재하지 않는 서버 입니다.' })
|
||||
else {
|
||||
|
||||
@ -5,7 +5,10 @@ import ResponseWrapper from '@utils/ResponseWrapper'
|
||||
import RequestHandler from '@utils/RequestHandler'
|
||||
|
||||
const Users = RequestHandler().get(async (req: ApiRequest, res) => {
|
||||
console.log(req.query)
|
||||
const auth = req.headers.authorization
|
||||
? await get.BotAuthorization(req.headers.authorization)
|
||||
: await get.Authorization(req.cookies.token)
|
||||
if (!auth) return ResponseWrapper(res, { code: 401 })
|
||||
const user = await get.user.load(req.query?.id)
|
||||
if (!user) return ResponseWrapper(res, { code: 404, message: '존재하지 않는 유저 입니다.' })
|
||||
else return ResponseWrapper(res, { code: 200, data: user })
|
||||
|
||||
@ -9,9 +9,16 @@ import { ParsedUrlQuery } from 'querystring'
|
||||
import { getJosaPicker } from 'josa'
|
||||
|
||||
import { get } from '@utils/Query'
|
||||
import { checkUserFlag, cleanObject, makeBotURL, parseCookie, redirectTo } from '@utils/Tools'
|
||||
import { ManageBot, ManageBotSchema } from '@utils/Yup'
|
||||
import { botCategories, botCategoryDescription, library } from '@utils/Constants'
|
||||
import {
|
||||
checkBotFlag,
|
||||
checkUserFlag,
|
||||
cleanObject,
|
||||
makeBotURL,
|
||||
parseCookie,
|
||||
redirectTo,
|
||||
} from '@utils/Tools'
|
||||
import { ManageBot, getManageBotSchema } from '@utils/Yup'
|
||||
import { botCategories, botCategoryDescription, botEnforcements, library } from '@utils/Constants'
|
||||
import { Bot, Theme, User } from '@types'
|
||||
import { getToken } from '@utils/Csrf'
|
||||
import Fetch from '@utils/Fetch'
|
||||
@ -58,7 +65,7 @@ const ManageBotPage: NextPage<ManageBotProps> = ({ bot, user, csrfToken, theme }
|
||||
else return null
|
||||
}
|
||||
|
||||
if (!bot) return <NotFound />
|
||||
if (!bot?.id) return <NotFound />
|
||||
if (!user)
|
||||
return (
|
||||
<Login>
|
||||
@ -70,6 +77,7 @@ const ManageBotPage: NextPage<ManageBotProps> = ({ bot, user, csrfToken, theme }
|
||||
!checkUserFlag(user.flags, 'staff')
|
||||
)
|
||||
return <Forbidden />
|
||||
const isPerkAvailable = checkBotFlag(bot.flags, 'trusted') || checkBotFlag(bot.flags, 'partnered')
|
||||
return (
|
||||
<Container paddingTop className='pb-10 pt-5'>
|
||||
<NextSeo title={`${bot.name} 수정하기`} description='봇의 정보를 수정합니다.' />
|
||||
@ -81,21 +89,29 @@ const ManageBotPage: NextPage<ManageBotProps> = ({ bot, user, csrfToken, theme }
|
||||
prefix: bot.prefix,
|
||||
library: bot.lib,
|
||||
category: bot.category,
|
||||
enforcements: bot.enforcements,
|
||||
intro: bot.intro,
|
||||
desc: bot.desc,
|
||||
website: bot.web,
|
||||
url: bot.url,
|
||||
git: bot.git,
|
||||
discord: bot.discord,
|
||||
vanity: isPerkAvailable && bot.vanity,
|
||||
banner: isPerkAvailable && bot.banner,
|
||||
bg: isPerkAvailable && bot.bg,
|
||||
_csrf: csrfToken,
|
||||
})}
|
||||
validationSchema={ManageBotSchema}
|
||||
validationSchema={getManageBotSchema(isPerkAvailable)}
|
||||
onSubmit={submitBot}
|
||||
>
|
||||
{({ errors, touched, values, setFieldTouched, setFieldValue }) => (
|
||||
<Form>
|
||||
<div className='text-center md:flex md:text-left'>
|
||||
<DiscordAvatar userID={bot.id} className='mx-auto rounded-full md:mx-1' hash={bot.avatar}/>
|
||||
<div className='text-ceznter md:flex md:text-left'>
|
||||
<DiscordAvatar
|
||||
userID={bot.id}
|
||||
className='mx-auto rounded-full md:mx-1'
|
||||
hash={bot.avatar}
|
||||
/>
|
||||
<div className='px-8 py-6 md:w-2/3'>
|
||||
<h1 className='text-3xl font-bold'>
|
||||
{bot.name}#{bot.tag}
|
||||
@ -161,7 +177,11 @@ const ManageBotPage: NextPage<ManageBotProps> = ({ bot, user, csrfToken, theme }
|
||||
error={errors.category && touched.category ? (errors.category as string) : null}
|
||||
>
|
||||
<Selects
|
||||
options={botCategories.map((el) => ({ label: el, value: el, description: botCategoryDescription[el] }))}
|
||||
options={botCategories.map((el) => ({
|
||||
label: el,
|
||||
value: el,
|
||||
description: botCategoryDescription[el],
|
||||
}))}
|
||||
handleChange={(value) => {
|
||||
setFieldValue(
|
||||
'category',
|
||||
@ -269,6 +289,83 @@ const ManageBotPage: NextPage<ManageBotProps> = ({ bot, user, csrfToken, theme }
|
||||
<Markdown text={values.desc} />
|
||||
</Segment>
|
||||
</Label>
|
||||
{isPerkAvailable && (
|
||||
<>
|
||||
<Divider />
|
||||
<h2 className='pt-2 text-2xl font-semibold text-koreanbots-green'>
|
||||
신뢰된 봇 특전 설정
|
||||
</h2>
|
||||
<span className='mt-1 text-sm text-gray-400'>
|
||||
신뢰된 봇의 혜택을 만나보세요. (커스텀 URL과 배너/배경 이미지는 이용약관 및
|
||||
가이드라인을 준수해야하며 위반 시 신뢰된 봇 자격이 박탈될 수 있습니다.)
|
||||
</span>
|
||||
<Label
|
||||
For='vanity'
|
||||
label='한디리 커스텀 URL'
|
||||
labelDesc='고유한 커스텀 URL을 설정해주세요.'
|
||||
error={errors.vanity && touched.vanity ? errors.vanity : null}
|
||||
>
|
||||
<div className='flex items-center'>
|
||||
koreanbots.dev/bots/
|
||||
<Input name='vanity' placeholder='koreanbots' />
|
||||
</div>
|
||||
</Label>
|
||||
<Label
|
||||
For='banner'
|
||||
label='배너 URL'
|
||||
labelDesc='봇 목록의 카드에 표시되는 이미지입니다.'
|
||||
error={errors.banner && touched.banner ? errors.banner : null}
|
||||
>
|
||||
<Input name='banner' placeholder='https://koreanbots.dev/logo.png' />
|
||||
</Label>
|
||||
<Label
|
||||
For='bg'
|
||||
label='배경 URL'
|
||||
labelDesc='봇 페이지 배경에 표시되는 이미지입니다.'
|
||||
error={errors.bg && touched.bg ? errors.bg : null}
|
||||
>
|
||||
<Input name='bg' placeholder='https://koreanbots.dev/logo.png' />
|
||||
</Label>
|
||||
</>
|
||||
)}
|
||||
<Divider />
|
||||
<Label
|
||||
For='enforcements'
|
||||
label='필수 고지 내용'
|
||||
labelDesc='내용에 해당하는 경우 필수로 선택해야 합니다.'
|
||||
required
|
||||
error={
|
||||
errors.enforcements && touched.enforcements ? (errors.enforcements as string) : null
|
||||
}
|
||||
>
|
||||
<Selects
|
||||
options={Object.entries(botEnforcements)
|
||||
.filter(([k]) => k === 'NONE' || !values.enforcements.includes('NONE'))
|
||||
.map(([k, v]) => ({
|
||||
label: v.label,
|
||||
value: k,
|
||||
}))}
|
||||
handleChange={(values) => {
|
||||
if (values.some((i) => i.value === 'NONE')) {
|
||||
setFieldValue('enforcements', ['NONE'])
|
||||
} else {
|
||||
setFieldValue(
|
||||
'enforcements',
|
||||
values.map((v) => v.value)
|
||||
)
|
||||
}
|
||||
}}
|
||||
handleTouch={() => setFieldTouched('enforcements', true)}
|
||||
values={values.enforcements ?? ([] as string[])}
|
||||
setValues={(values) => {
|
||||
if (values.includes('NONE')) {
|
||||
setFieldValue('enforcements', ['NONE'])
|
||||
} else {
|
||||
setFieldValue('enforcements', values)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Label>
|
||||
<Divider />
|
||||
<p className='mb-5 mt-2 text-base'>
|
||||
<span className='font-semibold text-red-500'> *</span> = 필수 항목
|
||||
@ -574,9 +671,11 @@ const ManageBotPage: NextPage<ManageBotProps> = ({ bot, user, csrfToken, theme }
|
||||
export const getServerSideProps = async (ctx: Context) => {
|
||||
const parsed = parseCookie(ctx.req)
|
||||
const user = await get.Authorization(parsed?.token)
|
||||
const bot = await get.bot.load(ctx.query.id)
|
||||
const spec = await get.botSpec(bot?.id || '', user || '')
|
||||
return {
|
||||
props: {
|
||||
bot: await get.bot.load(ctx.query.id),
|
||||
bot: { ...bot, banner: spec?.banner || null, bg: spec?.bg || null },
|
||||
user: await get.user.load(user || ''),
|
||||
csrfToken: getToken(ctx.req, ctx.res),
|
||||
},
|
||||
|
||||
@ -11,7 +11,7 @@ import { SnowflakeUtil } from 'discord.js'
|
||||
import { ParsedUrlQuery } from 'querystring'
|
||||
import { Bot, ResponseProps, Theme, User } from '@types'
|
||||
|
||||
import { git, KoreanbotsEndPoints, reportCats, Status } from '@utils/Constants'
|
||||
import { botEnforcements, git, KoreanbotsEndPoints, reportCats, Status } from '@utils/Constants'
|
||||
import { get } from '@utils/Query'
|
||||
import Day from '@utils/Day'
|
||||
import { ReportSchema } from '@utils/Yup'
|
||||
@ -116,13 +116,29 @@ const Bots: NextPage<BotsProps> = ({ data, desc, date, user, theme, csrfToken })
|
||||
로 문의해주세요.
|
||||
</p>
|
||||
</Message>
|
||||
) : data.enforcements.filter((i) => i !== 'NONE').length > 0 ? (
|
||||
<Message type='warning'>
|
||||
<h2 className='text-lg font-extrabold'>이 봇은 기능에 제한을 두고 있습니다.</h2>
|
||||
<p>
|
||||
{data.enforcements
|
||||
.filter((i) => i !== 'NONE')
|
||||
.map((i) => (
|
||||
<li key={i}>{botEnforcements[i].description}</li>
|
||||
))}
|
||||
</p>
|
||||
</Message>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</div>
|
||||
<div className='w-full lg:flex'>
|
||||
<div className='w-full text-center lg:w-2/12'>
|
||||
<DiscordAvatar userID={data.id} size={256} className='w-full rounded-full' hash={data.avatar}/>
|
||||
<DiscordAvatar
|
||||
userID={data.id}
|
||||
size={256}
|
||||
className='w-full rounded-full'
|
||||
hash={data.avatar}
|
||||
/>
|
||||
</div>
|
||||
<div className='w-full grow px-5 py-12 text-center lg:w-5/12 lg:text-left'>
|
||||
<Tag
|
||||
@ -158,7 +174,7 @@ const Bots: NextPage<BotsProps> = ({ data, desc, date, user, theme, csrfToken })
|
||||
</p>
|
||||
</div>
|
||||
<div className='w-full lg:w-1/4'>
|
||||
{(data.state === 'ok' && !checkBotFlag(data.flags, 'private')) && (
|
||||
{data.state === 'ok' && !checkBotFlag(data.flags, 'private') && (
|
||||
<LongButton newTab href={`/bots/${router.query.id}/invite`}>
|
||||
<h4 className='whitespace-nowrap'>
|
||||
<i className='fas fa-user-plus text-discord-blurple' /> 초대하기
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { NextPage } from 'next'
|
||||
import Link from 'next/link'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { Field, Form, Formik } from 'formik'
|
||||
import { NextPage } from 'next'
|
||||
import dynamic from 'next/dynamic'
|
||||
import Link from 'next/link'
|
||||
|
||||
import { Bot, CsrfContext, ResponseProps, User } from '@types'
|
||||
import { get } from '@utils/Query'
|
||||
@ -9,15 +9,15 @@ import { makeBotURL, parseCookie } from '@utils/Tools'
|
||||
|
||||
import { ParsedUrlQuery } from 'querystring'
|
||||
|
||||
import NotFound from 'pages/404'
|
||||
import { getToken } from '@utils/Csrf'
|
||||
import { DMCA, TextField } from '@components/ReportTemplate'
|
||||
import { useState } from 'react'
|
||||
import { reportCats } from '@utils/Constants'
|
||||
import { getToken } from '@utils/Csrf'
|
||||
import Fetch from '@utils/Fetch'
|
||||
import { ReportSchema } from '@utils/Yup'
|
||||
import { getJosaPicker } from 'josa'
|
||||
import { reportCats } from '@utils/Constants'
|
||||
import { NextSeo } from 'next-seo'
|
||||
import NotFound from 'pages/404'
|
||||
import { useState } from 'react'
|
||||
|
||||
const Container = dynamic(() => import('@components/Container'))
|
||||
const Message = dynamic(() => import('@components/Message'))
|
||||
@ -37,7 +37,7 @@ const ReportBot: NextPage<ReportBotProps> = ({ data, user, csrfToken }) => {
|
||||
<NextSeo title={`${data.name} 신고하기`} />
|
||||
<Link href={makeBotURL(data)} className='text-blue-500 hover:opacity-80'>
|
||||
<i className='fas fa-arrow-left mb-3 mt-3' /> <strong>{data.name}</strong>
|
||||
{getJosaPicker('로')(data.name)}돌아가기
|
||||
{getJosaPicker('로')(data.name)} 돌아가기
|
||||
</Link>
|
||||
{reportRes?.code === 200 ? (
|
||||
<Message type='success'>
|
||||
|
||||
@ -1,24 +1,24 @@
|
||||
import { NextPage } from 'next'
|
||||
import Link from 'next/link'
|
||||
import dynamic from 'next/dynamic'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import { Bot, CsrfContext, ResponseProps, Theme, User } from '@types'
|
||||
import { get } from '@utils/Query'
|
||||
import { makeBotURL, parseCookie, checkBotFlag } from '@utils/Tools'
|
||||
import { checkBotFlag, makeBotURL, parseCookie } from '@utils/Tools'
|
||||
|
||||
import { ParsedUrlQuery } from 'querystring'
|
||||
|
||||
import NotFound from 'pages/404'
|
||||
import { getToken } from '@utils/Csrf'
|
||||
import Captcha from '@components/Captcha'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import Fetch from '@utils/Fetch'
|
||||
import Day from '@utils/Day'
|
||||
import { getJosaPicker } from 'josa'
|
||||
import { KoreanbotsEndPoints } from '@utils/Constants'
|
||||
import { NextSeo } from 'next-seo'
|
||||
import SetNotification, { getFCMToken } from '@components/FCM'
|
||||
import { KoreanbotsEndPoints } from '@utils/Constants'
|
||||
import { getToken } from '@utils/Csrf'
|
||||
import Day from '@utils/Day'
|
||||
import Fetch from '@utils/Fetch'
|
||||
import { getJosaPicker } from 'josa'
|
||||
import { NextSeo } from 'next-seo'
|
||||
import NotFound from 'pages/404'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
|
||||
const Container = dynamic(() => import('@components/Container'))
|
||||
const DiscordAvatar = dynamic(() => import('@components/DiscordAvatar'))
|
||||
@ -98,7 +98,7 @@ const VoteBot: NextPage<VoteBotProps> = ({ data, user, theme, csrfToken }) => {
|
||||
<Advertisement />
|
||||
<Link href={makeBotURL(data)} className='text-blue-500 hover:opacity-80'>
|
||||
<i className='fas fa-arrow-left mb-3 mt-3' /> <strong>{data.name}</strong>
|
||||
{getJosaPicker('로')(data.name)}돌아가기
|
||||
{getJosaPicker('로')(data.name)} 돌아가기
|
||||
</Link>
|
||||
<Segment className='mb-16 py-8'>
|
||||
<div className='text-center'>
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
import { NextPage } from 'next'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
const Reserved: NextPage = () => {
|
||||
const router = useRouter()
|
||||
router.push('/bots/iu')
|
||||
return <></>
|
||||
}
|
||||
|
||||
export default Reserved
|
||||
@ -42,7 +42,7 @@ const Security: NextPage<SecurityProps> = ({ bugReports }) => {
|
||||
</ul>
|
||||
<h1 className='mb-3 mt-6 text-3xl font-bold text-koreanbots-blue'>범위</h1>
|
||||
<ul className='list-inside list-disc'>
|
||||
{['koreanbots.dev 및 *.koreanbots.dev', 'kbots.link', '디스코드.한국'].map((el) => (
|
||||
{['koreanbots.dev 및 *.koreanbots.dev', 'listing.kr', 'discordlist.kr', '디스코드.한국'].map((el) => (
|
||||
<li key={el}>{el}</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
@ -42,7 +42,8 @@ const Servers: NextPage<ServersProps> = ({ data, desc, date, user, theme }) => {
|
||||
const [emojisModal, setEmojisModal] = useState(false)
|
||||
const [ownersModal, setOwnersModal] = useState(false)
|
||||
const [owners, setOwners] = useState<User[]>(null)
|
||||
const bg = checkBotFlag(data?.flags, 'trusted') && data?.banner
|
||||
const bg =
|
||||
(checkBotFlag(data?.flags, 'trusted') || checkBotFlag(data?.flags, 'partnered')) && data?.bg
|
||||
const router = useRouter()
|
||||
useEffect(() => {
|
||||
if (data)
|
||||
@ -143,7 +144,12 @@ const Servers: NextPage<ServersProps> = ({ data, desc, date, user, theme }) => {
|
||||
</div>
|
||||
<div className='w-full lg:flex'>
|
||||
<div className='w-full text-center lg:w-2/12'>
|
||||
<ServerIcon id={data.id} size={256} className='w-full rounded-full' hash={data.icon} />
|
||||
<ServerIcon
|
||||
id={data.id}
|
||||
size={256}
|
||||
className='w-full rounded-full'
|
||||
hash={data.icon}
|
||||
/>
|
||||
</div>
|
||||
<div className='w-full grow px-5 py-12 text-center lg:w-5/12 lg:text-left'>
|
||||
<h1 className='mb-2 mt-3 text-4xl font-bold' style={bg ? { color: 'white' } : {}}>
|
||||
|
||||
@ -1,23 +1,23 @@
|
||||
import { NextPage } from 'next'
|
||||
import Link from 'next/link'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { Field, Form, Formik } from 'formik'
|
||||
import { NextPage } from 'next'
|
||||
import dynamic from 'next/dynamic'
|
||||
import Link from 'next/link'
|
||||
|
||||
import { Server, CsrfContext, ResponseProps, User } from '@types'
|
||||
import { CsrfContext, ResponseProps, Server, User } from '@types'
|
||||
import { get } from '@utils/Query'
|
||||
import { makeServerURL, parseCookie } from '@utils/Tools'
|
||||
|
||||
import { ParsedUrlQuery } from 'querystring'
|
||||
|
||||
import NotFound from 'pages/404'
|
||||
import { getToken } from '@utils/Csrf'
|
||||
import { DMCA, TextField } from '@components/ReportTemplate'
|
||||
import { useState } from 'react'
|
||||
import { serverReportCats } from '@utils/Constants'
|
||||
import { getToken } from '@utils/Csrf'
|
||||
import Fetch from '@utils/Fetch'
|
||||
import { ReportSchema } from '@utils/Yup'
|
||||
import { getJosaPicker } from 'josa'
|
||||
import { serverReportCats } from '@utils/Constants'
|
||||
import { NextSeo } from 'next-seo'
|
||||
import NotFound from 'pages/404'
|
||||
import { useState } from 'react'
|
||||
|
||||
const Container = dynamic(() => import('@components/Container'))
|
||||
const Message = dynamic(() => import('@components/Message'))
|
||||
@ -37,7 +37,7 @@ const ReportServer: NextPage<ReportServerProps> = ({ data, user, csrfToken }) =>
|
||||
<NextSeo title={`${data.name} 신고하기`} />
|
||||
<Link href={makeServerURL(data)} className='text-blue-500 hover:opacity-80'>
|
||||
<i className='fas fa-arrow-left mb-3 mt-3' /> <strong>{data.name}</strong>
|
||||
{getJosaPicker('로')(data.name)}돌아가기
|
||||
{getJosaPicker('로')(data.name)} 돌아가기
|
||||
</Link>
|
||||
{reportRes?.code === 200 ? (
|
||||
<Message type='success'>
|
||||
|
||||
@ -1,24 +1,24 @@
|
||||
import { NextPage } from 'next'
|
||||
import Link from 'next/link'
|
||||
import dynamic from 'next/dynamic'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import { CsrfContext, ResponseProps, Server, Theme, User } from '@types'
|
||||
import { get } from '@utils/Query'
|
||||
import { parseCookie, checkServerFlag, makeServerURL } from '@utils/Tools'
|
||||
import { checkServerFlag, makeServerURL, parseCookie } from '@utils/Tools'
|
||||
|
||||
import { ParsedUrlQuery } from 'querystring'
|
||||
|
||||
import NotFound from 'pages/404'
|
||||
import { getToken } from '@utils/Csrf'
|
||||
import Captcha from '@components/Captcha'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import Fetch from '@utils/Fetch'
|
||||
import Day from '@utils/Day'
|
||||
import { getJosaPicker } from 'josa'
|
||||
import { KoreanbotsEndPoints } from '@utils/Constants'
|
||||
import { NextSeo } from 'next-seo'
|
||||
import SetNotification, { getFCMToken } from '@components/FCM'
|
||||
import { KoreanbotsEndPoints } from '@utils/Constants'
|
||||
import { getToken } from '@utils/Csrf'
|
||||
import Day from '@utils/Day'
|
||||
import Fetch from '@utils/Fetch'
|
||||
import { getJosaPicker } from 'josa'
|
||||
import { NextSeo } from 'next-seo'
|
||||
import NotFound from 'pages/404'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
|
||||
const Container = dynamic(() => import('@components/Container'))
|
||||
const ServerIcon = dynamic(() => import('@components/ServerIcon'))
|
||||
@ -99,7 +99,7 @@ const VoteServer: NextPage<VoteServerProps> = ({ data, user, theme, csrfToken })
|
||||
<Advertisement />
|
||||
<Link href={makeServerURL(data)} className='text-blue-500 hover:opacity-80'>
|
||||
<i className='fas fa-arrow-left mb-3 mt-3' /> <strong>{data.name}</strong>
|
||||
{getJosaPicker('로')(data.name)}돌아가기
|
||||
{getJosaPicker('로')(data.name)} 돌아가기
|
||||
</Link>
|
||||
<Segment className='mb-16 py-8'>
|
||||
<div className='text-center'>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { NextPage } from 'next'
|
||||
import Link from 'next/link'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { Field, Form, Formik } from 'formik'
|
||||
import { NextPage } from 'next'
|
||||
import dynamic from 'next/dynamic'
|
||||
import Link from 'next/link'
|
||||
|
||||
import { CsrfContext, ResponseProps, User } from '@types'
|
||||
import { get } from '@utils/Query'
|
||||
@ -9,15 +9,15 @@ import { makeUserURL, parseCookie } from '@utils/Tools'
|
||||
|
||||
import { ParsedUrlQuery } from 'querystring'
|
||||
|
||||
import NotFound from 'pages/404'
|
||||
import { getToken } from '@utils/Csrf'
|
||||
import { DMCA, TextField } from '@components/ReportTemplate'
|
||||
import { useState } from 'react'
|
||||
import { reportCats } from '@utils/Constants'
|
||||
import { getToken } from '@utils/Csrf'
|
||||
import Fetch from '@utils/Fetch'
|
||||
import { ReportSchema } from '@utils/Yup'
|
||||
import { getJosaPicker } from 'josa'
|
||||
import { reportCats } from '@utils/Constants'
|
||||
import { NextSeo } from 'next-seo'
|
||||
import NotFound from 'pages/404'
|
||||
import { useState } from 'react'
|
||||
|
||||
const Container = dynamic(() => import('@components/Container'))
|
||||
const Message = dynamic(() => import('@components/Message'))
|
||||
@ -50,7 +50,7 @@ const ReportUser: NextPage<ReportUserProps> = ({ data, user, csrfToken }) => {
|
||||
<NextSeo title={`${data.globalName} 신고하기`} />
|
||||
<Link href={makeUserURL(data)} className='text-blue-500 hover:opacity-80'>
|
||||
<i className='fas fa-arrow-left mb-3 mt-3' /> <strong>{data.globalName}</strong>
|
||||
{getJosaPicker('로')(data.globalName)}돌아가기
|
||||
{getJosaPicker('로')(data.globalName)} 돌아가기
|
||||
</Link>
|
||||
{reportRes?.code === 200 ? (
|
||||
<Message type='success'>
|
||||
|
||||
BIN
public/logo-transparent.png
Normal file
BIN
public/logo-transparent.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
2
types/global.d.ts
vendored
2
types/global.d.ts
vendored
@ -2,6 +2,7 @@
|
||||
import * as Yup from 'yup'
|
||||
import { Client } from 'discord.js'
|
||||
import NotificationManager from '@utils/NotificationManager'
|
||||
import { CacheManager } from '@utils/Query'
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
@ -14,6 +15,7 @@ declare global {
|
||||
var kodl: Client
|
||||
var serverlist: Client
|
||||
var notification: NotificationManager
|
||||
var get: CacheManager
|
||||
interface Navigator {
|
||||
standalone?: boolean
|
||||
}
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
import { botEnforcements } from '@utils/Constants'
|
||||
import type { GuildFeature } from 'discord.js'
|
||||
import type { IncomingMessage } from 'http'
|
||||
import type { NextPageContext } from 'next'
|
||||
|
||||
export type Nullable<T> = T | null
|
||||
|
||||
export type ValueOf<T> = T[keyof T]
|
||||
|
||||
export interface Bot {
|
||||
id: string
|
||||
name: string
|
||||
@ -25,11 +28,14 @@ export interface Bot {
|
||||
url: string | null
|
||||
discord: string | null
|
||||
vanity: string | null
|
||||
enforcements: BotEnforcementKeys[]
|
||||
bg: string
|
||||
banner: string
|
||||
owners: User[] | string[]
|
||||
}
|
||||
|
||||
export type BotEnforcementKeys = keyof typeof botEnforcements
|
||||
|
||||
export interface RawGuild {
|
||||
id: string
|
||||
name: string
|
||||
@ -89,6 +95,8 @@ export interface BotSpec {
|
||||
webhookURL: string | null
|
||||
webhookStatus: WebhookStatus
|
||||
token: string
|
||||
banner: string | null
|
||||
bg: string | null
|
||||
}
|
||||
|
||||
export interface ServerSpec {
|
||||
@ -351,7 +359,7 @@ export interface ImageOptions {
|
||||
export interface KoreanbotsImageOptions {
|
||||
format?: 'webp' | 'png' | 'gif'
|
||||
size?: 128 | 256 | 512
|
||||
hash?: string;
|
||||
hash?: string
|
||||
}
|
||||
|
||||
export enum DiscordImageType {
|
||||
|
||||
@ -102,7 +102,7 @@ export const botCategoryDescription = {
|
||||
전적: '게임 유저 전적이나 게임 정보 등 여러 전적에 대해 다룹니다.',
|
||||
게임: '봇에 자체적인 게임 콘텐츠가 있습니다.',
|
||||
도박: '봇 내 가상 재화를 이용해 도박을 할 수 있습니다.',
|
||||
로깅: '유저의 출입, 메시지 수정 / 삭제 등을 로그로 남길 수 있습니다.',
|
||||
로깅: '유저의 출입, 메시지 수정 / 삭제 등 각종 기록을 디스코드 채널에 남길 수 있습니다.',
|
||||
'빗금 명령어': '메시지 기반이 아닌 빗금 명령어를 사용합니다.',
|
||||
'웹 대시보드': '웹사이트를 통해 봇을 조작할 수 있습니다.',
|
||||
밈: '각종 밈을 다루고 있습니다.',
|
||||
@ -120,6 +120,29 @@ export const botCategoryDescription = {
|
||||
마인크래프트: '게임 "마인크래프트"에 관련된 기능을 다룹니다.',
|
||||
}
|
||||
|
||||
export const botEnforcements = {
|
||||
NONE: {
|
||||
label: '해당사항이 없습니다.',
|
||||
description: '',
|
||||
},
|
||||
JOIN_PARTIALLY_ENFORCED: {
|
||||
label: '지정된 서버에 참여해야만 사용이 가능한 기능이 있습니다',
|
||||
description: '봇의 일부 명령어는 봇이 지정한 특정 디스코드 서버에 참여해야 사용할 수 있습니다.',
|
||||
},
|
||||
JOIN_ENFORCED: {
|
||||
label: '지정된 서버에 참여하지 않으면 봇의 핵심 기능을 사용할 수 없습니다',
|
||||
description: '봇의 핵심 기능은 봇이 지정한 특정 디스코드 서버에 참여해야 사용할 수 있습니다.',
|
||||
},
|
||||
LICENSE_PARTIALLY_ENFORCED: {
|
||||
label: '유료 구매가 필요한 기능이 있습니다',
|
||||
description: '봇의 일부 명령어는 유료 구매가 필요합니다.',
|
||||
},
|
||||
LICENSE_ENFORCED: {
|
||||
label: '유료 구매 없이는 봇의 핵심 기능을 사용할 수 없습니다',
|
||||
description: '유료 구매 없이는 봇의 핵심 기능을 사용할 수 없습니다.',
|
||||
},
|
||||
} as const
|
||||
|
||||
export const botCategoryIcon = {
|
||||
관리: 'fas fa-cogs',
|
||||
뮤직: 'fas fa-music',
|
||||
@ -626,3 +649,10 @@ export const GuildPermissions = {
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
export const reservedVanityBypass = [
|
||||
'653534001742741552',
|
||||
'784618064167698472',
|
||||
'653083797763522580',
|
||||
'807561475014262785',
|
||||
]
|
||||
|
||||
@ -57,6 +57,10 @@ export const webhookClients = {
|
||||
{ url: process.env.REPORT_WEBHOOK_URL ?? dummyURL },
|
||||
{ allowedMentions: { parse: [] } }
|
||||
),
|
||||
noticeLog: new Discord.WebhookClient(
|
||||
{ url: process.env.NOTICE_LOG_WEBHOOK_URL ?? dummyURL },
|
||||
{ allowedMentions: { parse: [] } }
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ import knex from 'knex'
|
||||
export default knex({
|
||||
client: 'mysql',
|
||||
connection: {
|
||||
port: Number(process.env.MYSQL_PORT) || 3306,
|
||||
host: process.env.MYSQL_HOST || 'localhost',
|
||||
user: process.env.MYSQL_USER || 'root',
|
||||
password: process.env.MYSQL_PASSWORD || 'test',
|
||||
|
||||
@ -62,6 +62,7 @@ async function getBot(id: string, topLevel = true): Promise<Bot> {
|
||||
'bots.status',
|
||||
'bots.trusted',
|
||||
'bots.partnered',
|
||||
'bots.enforcements',
|
||||
'bots.discord',
|
||||
'bots.state',
|
||||
'bots.vanity',
|
||||
@ -100,7 +101,9 @@ async function getBot(id: string, topLevel = true): Promise<Bot> {
|
||||
res.name = name
|
||||
res.category = JSON.parse(res.category)
|
||||
res.owners = JSON.parse(res.owners)
|
||||
|
||||
res.banner = res.banner ? camoUrl(res.banner) : null
|
||||
res.bg = res.bg ? camoUrl(res.bg) : null
|
||||
res.enforcements = JSON.parse(res.enforcements ?? '[]')
|
||||
if (discordBot.flags.bitfield & UserFlags.BotHTTPInteractions) {
|
||||
res.status = 'online'
|
||||
} else if (botMember) {
|
||||
@ -446,6 +449,7 @@ async function getBotSubmit(id: string, date: number): Promise<SubmittedBot> {
|
||||
'id',
|
||||
'date',
|
||||
'category',
|
||||
'enforcements',
|
||||
'lib',
|
||||
'prefix',
|
||||
'intro',
|
||||
@ -461,6 +465,7 @@ async function getBotSubmit(id: string, date: number): Promise<SubmittedBot> {
|
||||
.where({ id, date })
|
||||
if (res.length === 0) return null
|
||||
res[0].category = JSON.parse(res[0].category)
|
||||
res[0].enforcements = JSON.parse(res[0].enforcements || '[]')
|
||||
res[0].owner = await get.user.load(res[0].owner)
|
||||
return res[0]
|
||||
}
|
||||
@ -472,6 +477,7 @@ async function getBotSubmits(id: string): Promise<SubmittedBot[]> {
|
||||
'id',
|
||||
'date',
|
||||
'category',
|
||||
'enforcements',
|
||||
'lib',
|
||||
'prefix',
|
||||
'intro',
|
||||
@ -490,6 +496,7 @@ async function getBotSubmits(id: string): Promise<SubmittedBot[]> {
|
||||
res = await Promise.all(
|
||||
res.map(async (el) => {
|
||||
el.category = JSON.parse(el.category)
|
||||
el.enforcements = JSON.parse(el.enforcements)
|
||||
el.owner = owner
|
||||
return el
|
||||
})
|
||||
@ -634,6 +641,7 @@ async function submitBot(
|
||||
git: data.git,
|
||||
url: data.url,
|
||||
category: JSON.stringify(data.category),
|
||||
enforcements: JSON.stringify(data.enforcements),
|
||||
discord: data.discord,
|
||||
state: 0,
|
||||
})
|
||||
@ -676,7 +684,14 @@ async function submitServer(
|
||||
|
||||
async function getBotSpec(id: string, userID: string): Promise<BotSpec | null> {
|
||||
const res = await knex('bots')
|
||||
.select(['bots.id', 'bots.token', 'bots.webhook_url', 'bots.webhook_status'])
|
||||
.select([
|
||||
'bots.id',
|
||||
'bots.token',
|
||||
'bots.webhook_url',
|
||||
'bots.webhook_status',
|
||||
'bots.banner',
|
||||
'bots.bg',
|
||||
])
|
||||
.leftJoin('owners_mapping', 'bots.id', 'owners_mapping.target_id')
|
||||
.where('owners_mapping.user_id', userID)
|
||||
.andWhere('owners_mapping.type', ObjectType.Bot)
|
||||
@ -688,6 +703,8 @@ async function getBotSpec(id: string, userID: string): Promise<BotSpec | null> {
|
||||
token: res[0].token,
|
||||
webhookURL: res[0].webhook_url,
|
||||
webhookStatus: res[0].webhook_status,
|
||||
banner: res[0].banner,
|
||||
bg: res[0].bg,
|
||||
}
|
||||
}
|
||||
|
||||
@ -733,6 +750,10 @@ async function updateBot(id: string, data: ManageBot): Promise<number> {
|
||||
category: JSON.stringify(data.category),
|
||||
intro: data.intro,
|
||||
desc: data.desc,
|
||||
vanity: data.vanity,
|
||||
enforcements: JSON.stringify(data.enforcements),
|
||||
banner: data.banner,
|
||||
bg: data.bg,
|
||||
})
|
||||
.where({ id })
|
||||
|
||||
@ -1120,6 +1141,7 @@ async function approveBotSubmission(id: string, date: number) {
|
||||
'id',
|
||||
'date',
|
||||
'category',
|
||||
'enforcements',
|
||||
'lib',
|
||||
'prefix',
|
||||
'intro',
|
||||
@ -1146,6 +1168,7 @@ async function approveBotSubmission(id: string, date: number) {
|
||||
web: data.web,
|
||||
git: data.git,
|
||||
category: data.category,
|
||||
enforcements: data.enforcements,
|
||||
discord: data.discord,
|
||||
token: sign({ id }),
|
||||
})
|
||||
@ -1185,7 +1208,7 @@ async function viewBot(id: string) {
|
||||
await Bots.findByIdAndUpdate(id, { $push: { viewMetrix: { count: 0 } } }, { upsert: true })
|
||||
}
|
||||
|
||||
export const get = {
|
||||
const _get = {
|
||||
discord: {
|
||||
user: new DataLoader(
|
||||
async (ids: string[]) =>
|
||||
@ -1400,6 +1423,14 @@ export const get = {
|
||||
},
|
||||
}
|
||||
|
||||
export type CacheManager = typeof _get
|
||||
|
||||
if (!global.get) {
|
||||
global.get = _get
|
||||
}
|
||||
|
||||
export const get = global.get
|
||||
|
||||
export const update = {
|
||||
assignToken,
|
||||
resetBotToken,
|
||||
|
||||
@ -1,4 +1,12 @@
|
||||
import urlRegex from 'url-regex-safe'
|
||||
const reservedVanityConst = [
|
||||
'koreanbots',
|
||||
'koreanservers',
|
||||
'koreanlist',
|
||||
'kbots',
|
||||
'kodl',
|
||||
'discord',
|
||||
]
|
||||
|
||||
export const ID = /^[0-9]{17,}$/
|
||||
export const Vanity = /^[A-Za-z\d-]+$/
|
||||
@ -12,3 +20,4 @@ export const Heading = '<h\\d id="(.+?)">(.*?)<\\/h(\\d)>'
|
||||
export const EmojiSyntax = ':(\\w+):'
|
||||
export const ImageTag = /<img\s[^>]*?alt\s*=\s*['"]([^'"]*?)['"][^>]*?>/
|
||||
export const markdownImage = /!\[([^\]]*)\]\((.*?)\s*("(?:.*[^"])")?\s*\)/g
|
||||
export const reservedVanity = new RegExp(`^((?!${reservedVanityConst.join('|')}).)*$`, 'i') // 예약되지 않음을 확인
|
||||
|
||||
60
utils/Yup.ts
60
utils/Yup.ts
@ -1,8 +1,15 @@
|
||||
import * as Yup from 'yup'
|
||||
import YupKorean from 'yup-locales-ko'
|
||||
import { ListType } from '@types'
|
||||
import { botCategories, library, reportCats, serverCategories } from '@utils/Constants'
|
||||
import { HTTPProtocol, ID, Prefix, Url, Vanity } from '@utils/Regex'
|
||||
import {
|
||||
botCategories,
|
||||
botEnforcements,
|
||||
library,
|
||||
reportCats,
|
||||
reservedVanityBypass,
|
||||
serverCategories,
|
||||
} from '@utils/Constants'
|
||||
import { HTTPProtocol, ID, Prefix, reservedVanity, Url, Vanity } from '@utils/Regex'
|
||||
|
||||
Yup.setLocale(YupKorean)
|
||||
Yup.addMethod(Yup.array, 'unique', function (message, mapper = (a) => a) {
|
||||
@ -168,6 +175,10 @@ export const AddBotSubmitSchema: Yup.SchemaOf<AddBotSubmit> = Yup.object({
|
||||
.min(100, '봇 설명은 최소 100자여야합니다.')
|
||||
.max(1500, '봇 설명은 최대 1500자여야합니다.')
|
||||
.required('봇 설명은 필수 항목입니다.'),
|
||||
enforcements: Yup.array(Yup.string().oneOf(Object.keys(botEnforcements)))
|
||||
.min(1, '최소 한 개의 선택지를 선택해주세요.')
|
||||
.unique('선택지는 중복될 수 없습니다.')
|
||||
.required('강제사항 명시는 필수 선택사항입니다.'),
|
||||
_csrf: Yup.string().required(),
|
||||
_captcha: Yup.string().required(),
|
||||
})
|
||||
@ -184,6 +195,7 @@ export interface AddBotSubmit {
|
||||
category: string | string[]
|
||||
intro: string
|
||||
desc: string
|
||||
enforcements: string[]
|
||||
_csrf: string
|
||||
_captcha: string
|
||||
}
|
||||
@ -257,7 +269,8 @@ export interface Report {
|
||||
_csrf: string
|
||||
}
|
||||
|
||||
export const ManageBotSchema: Yup.SchemaOf<ManageBot> = Yup.object({
|
||||
export function getManageBotSchema(perkAvailable = false) {
|
||||
const common = {
|
||||
prefix: Yup.string()
|
||||
.matches(Prefix, '접두사는 띄어쓰기로 시작할 수 없습니다.')
|
||||
.min(1, '접두사는 최소 1자여야합니다.')
|
||||
@ -296,8 +309,43 @@ export const ManageBotSchema: Yup.SchemaOf<ManageBot> = Yup.object({
|
||||
.min(100, '봇 설명은 최소 100자여야합니다.')
|
||||
.max(1500, '봇 설명은 최대 1500자여야합니다.')
|
||||
.required('봇 설명은 필수 항목입니다.'),
|
||||
enforcements: Yup.array(Yup.string().oneOf(Object.keys(botEnforcements)))
|
||||
.min(1, '최소 한 개의 선택지를 선택해주세요.')
|
||||
.unique('선택지는 중복될 수 없습니다.')
|
||||
.required('강제사항 명시는 필수 선택사항입니다.'),
|
||||
_csrf: Yup.string().required(),
|
||||
})
|
||||
}
|
||||
|
||||
const perk = {
|
||||
vanity: Yup.string()
|
||||
.matches(Vanity, '커스텀 URL은 영문만 포함할 수 있습니다.')
|
||||
.when('id', {
|
||||
is: (id: string) => reservedVanityBypass.includes(id),
|
||||
then: Yup.string(),
|
||||
otherwise: Yup.string().matches(
|
||||
reservedVanity,
|
||||
'예약어가 포함되었거나 사용할 수 없는 커스텀 URL입니다.'
|
||||
),
|
||||
})
|
||||
.min(2, '커스텀 URL은 최소 2자여야합니다.')
|
||||
.max(32, '커스텀 URL은 최대 32자여야합니다.')
|
||||
.nullable(),
|
||||
banner: Yup.string()
|
||||
.matches(HTTPProtocol, 'http:// 또는 https:// 로 시작해야합니다.')
|
||||
.matches(Url, '올바른 배너 URL을 입력해주세요.')
|
||||
.max(612, 'URL은 최대 612자까지만 가능합니다.')
|
||||
.nullable(),
|
||||
bg: Yup.string()
|
||||
.matches(HTTPProtocol, 'http:// 또는 https:// 로 시작해야합니다.')
|
||||
.matches(Url, '올바른 배경 URL을 입력해주세요.')
|
||||
.max(612, 'URL은 최대 612자까지만 가능합니다.')
|
||||
.nullable(),
|
||||
}
|
||||
return Yup.object({
|
||||
...common,
|
||||
...(perkAvailable ? perk : {}),
|
||||
}) as Yup.SchemaOf<ManageBot>
|
||||
}
|
||||
|
||||
export interface ManageBot {
|
||||
prefix: string
|
||||
@ -309,6 +357,10 @@ export interface ManageBot {
|
||||
category: string[]
|
||||
intro: string
|
||||
desc: string
|
||||
vanity: string
|
||||
banner: string
|
||||
enforcements: string[]
|
||||
bg: string
|
||||
_csrf: string
|
||||
}
|
||||
|
||||
|
||||
328
yarn.lock
328
yarn.lock
@ -796,6 +796,15 @@
|
||||
"@babel/highlight" "^7.22.13"
|
||||
chalk "^2.4.2"
|
||||
|
||||
"@babel/code-frame@^7.26.2":
|
||||
version "7.26.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85"
|
||||
integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.25.9"
|
||||
js-tokens "^4.0.0"
|
||||
picocolors "^1.0.0"
|
||||
|
||||
"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.22.5":
|
||||
version "7.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.5.tgz#b1f6c86a02d85d2dd3368a2b67c09add8cd0c255"
|
||||
@ -1031,6 +1040,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f"
|
||||
integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==
|
||||
|
||||
"@babel/helper-string-parser@^7.25.9":
|
||||
version "7.25.9"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c"
|
||||
integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==
|
||||
|
||||
"@babel/helper-validator-identifier@^7.22.20":
|
||||
version "7.22.20"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0"
|
||||
@ -1041,6 +1055,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193"
|
||||
integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==
|
||||
|
||||
"@babel/helper-validator-identifier@^7.25.9":
|
||||
version "7.25.9"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7"
|
||||
integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==
|
||||
|
||||
"@babel/helper-validator-option@^7.22.5":
|
||||
version "7.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac"
|
||||
@ -1057,13 +1076,12 @@
|
||||
"@babel/types" "^7.22.5"
|
||||
|
||||
"@babel/helpers@^7.22.5":
|
||||
version "7.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.5.tgz#74bb4373eb390d1ceed74a15ef97767e63120820"
|
||||
integrity sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q==
|
||||
version "7.26.10"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.26.10.tgz#6baea3cd62ec2d0c1068778d63cb1314f6637384"
|
||||
integrity sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==
|
||||
dependencies:
|
||||
"@babel/template" "^7.22.5"
|
||||
"@babel/traverse" "^7.22.5"
|
||||
"@babel/types" "^7.22.5"
|
||||
"@babel/template" "^7.26.9"
|
||||
"@babel/types" "^7.26.10"
|
||||
|
||||
"@babel/highlight@^7.22.13":
|
||||
version "7.22.20"
|
||||
@ -1093,6 +1111,13 @@
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719"
|
||||
integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==
|
||||
|
||||
"@babel/parser@^7.26.9":
|
||||
version "7.26.10"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.10.tgz#e9bdb82f14b97df6569b0b038edd436839c57749"
|
||||
integrity sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==
|
||||
dependencies:
|
||||
"@babel/types" "^7.26.10"
|
||||
|
||||
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.5":
|
||||
version "7.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz#87245a21cd69a73b0b81bcda98d443d6df08f05e"
|
||||
@ -1761,11 +1786,11 @@
|
||||
integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==
|
||||
|
||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.9", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.7", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
|
||||
version "7.22.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.5.tgz#8564dd588182ce0047d55d7a75e93921107b57ec"
|
||||
integrity sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==
|
||||
version "7.26.10"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.10.tgz#a07b4d8fa27af131a633d7b3524db803eb4764c2"
|
||||
integrity sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.11"
|
||||
regenerator-runtime "^0.14.0"
|
||||
|
||||
"@babel/template@^7.22.15":
|
||||
version "7.22.15"
|
||||
@ -1785,6 +1810,15 @@
|
||||
"@babel/parser" "^7.22.5"
|
||||
"@babel/types" "^7.22.5"
|
||||
|
||||
"@babel/template@^7.26.9":
|
||||
version "7.26.9"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.26.9.tgz#4577ad3ddf43d194528cff4e1fa6b232fa609bb2"
|
||||
integrity sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.26.2"
|
||||
"@babel/parser" "^7.26.9"
|
||||
"@babel/types" "^7.26.9"
|
||||
|
||||
"@babel/traverse@^7.22.5", "@babel/traverse@^7.7.2":
|
||||
version "7.23.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8"
|
||||
@ -1819,6 +1853,14 @@
|
||||
"@babel/helper-validator-identifier" "^7.22.20"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@babel/types@^7.26.10", "@babel/types@^7.26.9":
|
||||
version "7.26.10"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.10.tgz#396382f6335bd4feb65741eacfc808218f859259"
|
||||
integrity sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==
|
||||
dependencies:
|
||||
"@babel/helper-string-parser" "^7.25.9"
|
||||
"@babel/helper-validator-identifier" "^7.25.9"
|
||||
|
||||
"@bcoe/v8-coverage@^0.2.3":
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||
@ -2066,45 +2108,40 @@
|
||||
resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz#2cbcf822bf3764c9658c4d2e568bd0c0cb748016"
|
||||
integrity sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==
|
||||
|
||||
"@datadog/libdatadog@^0.3.0":
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/libdatadog/-/libdatadog-0.3.0.tgz#2fc1e2695872840bc8c356f66acf675da428d6f0"
|
||||
integrity sha512-TbP8+WyXfh285T17FnLeLUOPl4SbkRYMqKgcmknID2mXHNrbt5XJgW9bnDgsrrtu31Q7FjWWw2WolgRLWyzLRA==
|
||||
|
||||
"@datadog/native-appsec@8.3.0":
|
||||
version "8.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/native-appsec/-/native-appsec-8.3.0.tgz#91afd89d18d386be4da8a1b0e04500f2f8b5eb66"
|
||||
integrity sha512-RYHbSJ/MwJcJaLzaCaZvUyNLUKFbMshayIiv4ckpFpQJDiq1T8t9iM2k7008s75g1vRuXfsRNX7MaLn4aoFuWA==
|
||||
"@datadog/native-appsec@8.1.1":
|
||||
version "8.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/native-appsec/-/native-appsec-8.1.1.tgz#76aa34697e6ecbd3d9ef7e6938d3cdcfa689b1f3"
|
||||
integrity sha512-mf+Ym/AzET4FeUTXOs8hz0uLOSsVIUnavZPUx8YoKWK5lKgR2L+CLfEzOpjBwgFpDgbV8I1/vyoGelgGpsMKHA==
|
||||
dependencies:
|
||||
node-gyp-build "^3.9.0"
|
||||
|
||||
"@datadog/native-iast-rewriter@2.6.1":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/native-iast-rewriter/-/native-iast-rewriter-2.6.1.tgz#5e5393628c73c57dcf08256299c0e8cf71deb14f"
|
||||
integrity sha512-zv7cr/MzHg560jhAnHcO7f9pLi4qaYrBEcB+Gla0xkVouYSDsp8cGXIGG4fiGdAMHdt7SpDNS6+NcEAqD/v8Ig==
|
||||
"@datadog/native-iast-rewriter@2.5.0":
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/native-iast-rewriter/-/native-iast-rewriter-2.5.0.tgz#b613defe86e78168f750d1f1662d4ffb3cf002e6"
|
||||
integrity sha512-WRu34A3Wwp6oafX8KWNAbedtDaaJO+nzfYQht7pcJKjyC2ggfPeF7SoP+eDo9wTn4/nQwEOscSR4hkJqTRlpXQ==
|
||||
dependencies:
|
||||
lru-cache "^7.14.0"
|
||||
node-gyp-build "^4.5.0"
|
||||
|
||||
"@datadog/native-iast-taint-tracking@3.2.0":
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-3.2.0.tgz#9fb6823d82f934e12c06ea1baa7399ca80deb2ec"
|
||||
integrity sha512-Mc6FzCoyvU5yXLMsMS9yKnEqJMWoImAukJXolNWCTm+JQYCMf2yMsJ8pBAm7KyZKliamM9rCn7h7Tr2H3lXwjA==
|
||||
"@datadog/native-iast-taint-tracking@3.1.0":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-3.1.0.tgz#7b2ed7f8fad212d65e5ab03bcdea8b42a3051b2e"
|
||||
integrity sha512-rw6qSjmxmu1yFHVvZLXFt/rVq2tUZXocNogPLB8n7MPpA0jijNGb109WokWw5ITImiW91GcGDuBW6elJDVKouQ==
|
||||
dependencies:
|
||||
node-gyp-build "^3.9.0"
|
||||
|
||||
"@datadog/native-metrics@^3.1.0":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/native-metrics/-/native-metrics-3.1.0.tgz#c2378841accd9fdd6866d0e49bdf6e3d76e79f22"
|
||||
integrity sha512-yOBi4x0OQRaGNPZ2bx9TGvDIgEdQ8fkudLTFAe7gEM1nAlvFmbE5YfpH8WenEtTSEBwojSau06m2q7axtEEmCg==
|
||||
"@datadog/native-metrics@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/native-metrics/-/native-metrics-2.0.0.tgz#65bf03313ee419956361e097551db36173e85712"
|
||||
integrity sha512-YklGVwUtmKGYqFf1MNZuOHvTYdKuR4+Af1XkWcMD8BwOAjxmd9Z+97328rCOY8TFUJzlGUPaXzB8j2qgG/BMwA==
|
||||
dependencies:
|
||||
node-addon-api "^6.1.0"
|
||||
node-gyp-build "^3.9.0"
|
||||
|
||||
"@datadog/pprof@5.4.1":
|
||||
version "5.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/pprof/-/pprof-5.4.1.tgz#08c9bcf5d8efb2eeafdfc9f5bb5402f79fb41266"
|
||||
integrity sha512-IvpL96e/cuh8ugP5O8Czdup7XQOLHeIDgM5pac5W7Lc1YzGe5zTtebKFpitvb1CPw1YY+1qFx0pWGgKP2kOfHg==
|
||||
"@datadog/pprof@5.3.0":
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/pprof/-/pprof-5.3.0.tgz#c2f58d328ecced7f99887f1a559d7fe3aecb9219"
|
||||
integrity sha512-53z2Q3K92T6Pf4vz4Ezh8kfkVEvLzbnVqacZGgcbkP//q0joFzO8q00Etw1S6NdnCX0XmX08ULaF4rUI5r14mw==
|
||||
dependencies:
|
||||
delay "^5.0.0"
|
||||
node-gyp-build "<4.0"
|
||||
@ -2875,11 +2912,6 @@
|
||||
wrap-ansi "^8.1.0"
|
||||
wrap-ansi-cjs "npm:wrap-ansi@^7.0.0"
|
||||
|
||||
"@isaacs/ttlcache@^1.4.1":
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz#21fb23db34e9b6220c6ba023a0118a2dd3461ea2"
|
||||
integrity sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==
|
||||
|
||||
"@istanbuljs/load-nyc-config@^1.0.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
|
||||
@ -3145,10 +3177,10 @@
|
||||
dependencies:
|
||||
sparse-bitfield "^3.0.3"
|
||||
|
||||
"@next/env@14.2.22":
|
||||
version "14.2.22"
|
||||
resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.22.tgz#8898ae47595badbfacebfc1585f42a4e06a97301"
|
||||
integrity sha512-EQ6y1QeNQglNmNIXvwP/Bb+lf7n9WtgcWvtoFsHquVLCJUuxRs+6SfZ5EK0/EqkkLex4RrDySvKgKNN7PXip7Q==
|
||||
"@next/env@14.2.32":
|
||||
version "14.2.32"
|
||||
resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.32.tgz#6d1107e2b7cc8649ff3730b8b46deb4e8a6d38fa"
|
||||
integrity sha512-n9mQdigI6iZ/DF6pCTwMKeWgF2e8lg7qgt5M7HXMLtyhZYMnf/u905M18sSpPmHL9MKp9JHo56C6jrD2EvWxng==
|
||||
|
||||
"@next/eslint-plugin-next@13.4.7":
|
||||
version "13.4.7"
|
||||
@ -3157,50 +3189,50 @@
|
||||
dependencies:
|
||||
glob "7.1.7"
|
||||
|
||||
"@next/swc-darwin-arm64@14.2.22":
|
||||
version "14.2.22"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.22.tgz#2b3fcb42247ba951b19a48fc03f1d6fe65629baa"
|
||||
integrity sha512-HUaLiehovgnqY4TMBZJ3pDaOsTE1spIXeR10pWgdQVPYqDGQmHJBj3h3V6yC0uuo/RoY2GC0YBFRkOX3dI9WVQ==
|
||||
"@next/swc-darwin-arm64@14.2.32":
|
||||
version "14.2.32"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.32.tgz#83482a7282df899b73d916e02b02a189771e706c"
|
||||
integrity sha512-osHXveM70zC+ilfuFa/2W6a1XQxJTvEhzEycnjUaVE8kpUS09lDpiDDX2YLdyFCzoUbvbo5r0X1Kp4MllIOShw==
|
||||
|
||||
"@next/swc-darwin-x64@14.2.22":
|
||||
version "14.2.22"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.22.tgz#11ecc609e9530b3edf8ddfd1fd3bd6aca4e1bfda"
|
||||
integrity sha512-ApVDANousaAGrosWvxoGdLT0uvLBUC+srqOcpXuyfglA40cP2LBFaGmBjhgpxYk5z4xmunzqQvcIgXawTzo2uQ==
|
||||
"@next/swc-darwin-x64@14.2.32":
|
||||
version "14.2.32"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.32.tgz#1a9eb676a014e1fc999251f10288c25a0f81d6d1"
|
||||
integrity sha512-P9NpCAJuOiaHHpqtrCNncjqtSBi1f6QUdHK/+dNabBIXB2RUFWL19TY1Hkhu74OvyNQEYEzzMJCMQk5agjw1Qg==
|
||||
|
||||
"@next/swc-linux-arm64-gnu@14.2.22":
|
||||
version "14.2.22"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.22.tgz#4c08dd223e50c348f561af2285e27fb326ffabbf"
|
||||
integrity sha512-3O2J99Bk9aM+d4CGn9eEayJXHuH9QLx0BctvWyuUGtJ3/mH6lkfAPRI4FidmHMBQBB4UcvLMfNf8vF0NZT7iKw==
|
||||
"@next/swc-linux-arm64-gnu@14.2.32":
|
||||
version "14.2.32"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.32.tgz#7713a49abd555d6f698e766b1631b67d881b4ee4"
|
||||
integrity sha512-v7JaO0oXXt6d+cFjrrKqYnR2ubrD+JYP7nQVRZgeo5uNE5hkCpWnHmXm9vy3g6foMO8SPwL0P3MPw1c+BjbAzA==
|
||||
|
||||
"@next/swc-linux-arm64-musl@14.2.22":
|
||||
version "14.2.22"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.22.tgz#0b285336f145887d421b3762f3d7c75f847ec1b3"
|
||||
integrity sha512-H/hqfRz75yy60y5Eg7DxYfbmHMjv60Dsa6IWHzpJSz4MRkZNy5eDnEW9wyts9bkxwbOVZNPHeb3NkqanP+nGPg==
|
||||
"@next/swc-linux-arm64-musl@14.2.32":
|
||||
version "14.2.32"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.32.tgz#327efdffe97e56f5389a7889cdedbd676fdbb519"
|
||||
integrity sha512-tA6sIKShXtSJBTH88i0DRd6I9n3ZTirmwpwAqH5zdJoQF7/wlJXR8DkPmKwYl5mFWhEKr5IIa3LfpMW9RRwKmQ==
|
||||
|
||||
"@next/swc-linux-x64-gnu@14.2.22":
|
||||
version "14.2.22"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.22.tgz#a936b6cfea0364571102f0389c6368d6acf3e294"
|
||||
integrity sha512-LckLwlCLcGR1hlI5eiJymR8zSHPsuruuwaZ3H2uudr25+Dpzo6cRFjp/3OR5UYJt8LSwlXv9mmY4oI2QynwpqQ==
|
||||
"@next/swc-linux-x64-gnu@14.2.32":
|
||||
version "14.2.32"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.32.tgz#a3e7444613d0fe5c8ea4ead08d6a9c818246758c"
|
||||
integrity sha512-7S1GY4TdnlGVIdeXXKQdDkfDysoIVFMD0lJuVVMeb3eoVjrknQ0JNN7wFlhCvea0hEk0Sd4D1hedVChDKfV2jw==
|
||||
|
||||
"@next/swc-linux-x64-musl@14.2.22":
|
||||
version "14.2.22"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.22.tgz#0359497840d0b7d8c095d0d9735bc6aec68cef5d"
|
||||
integrity sha512-qGUutzmh0PoFU0fCSu0XYpOfT7ydBZgDfcETIeft46abPqP+dmePhwRGLhFKwZWxNWQCPprH26TjaTxM0Nv8mw==
|
||||
"@next/swc-linux-x64-musl@14.2.32":
|
||||
version "14.2.32"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.32.tgz#a2ec5b0a06c740d6740c938b1d4a614f1a13f018"
|
||||
integrity sha512-OHHC81P4tirVa6Awk6eCQ6RBfWl8HpFsZtfEkMpJ5GjPsJ3nhPe6wKAJUZ/piC8sszUkAgv3fLflgzPStIwfWg==
|
||||
|
||||
"@next/swc-win32-arm64-msvc@14.2.22":
|
||||
version "14.2.22"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.22.tgz#9fd249d49ffccf3388400ab24472c432cdd04c24"
|
||||
integrity sha512-K6MwucMWmIvMb9GlvT0haYsfIPxfQD8yXqxwFy4uLFMeXIb2TcVYQimxkaFZv86I7sn1NOZnpOaVk5eaxThGIw==
|
||||
"@next/swc-win32-arm64-msvc@14.2.32":
|
||||
version "14.2.32"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.32.tgz#b4d3e47c6b276fc4711deb978d04015d029d198d"
|
||||
integrity sha512-rORQjXsAFeX6TLYJrCG5yoIDj+NKq31Rqwn8Wpn/bkPNy5rTHvOXkW8mLFonItS7QC6M+1JIIcLe+vOCTOYpvg==
|
||||
|
||||
"@next/swc-win32-ia32-msvc@14.2.22":
|
||||
version "14.2.22"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.22.tgz#70d8d5a48e78c7382c3e0544af28c2788ca6b551"
|
||||
integrity sha512-5IhDDTPEbzPR31ZzqHe90LnNe7BlJUZvC4sA1thPJV6oN5WmtWjZ0bOYfNsyZx00FJt7gggNs6SrsX0UEIcIpA==
|
||||
"@next/swc-win32-ia32-msvc@14.2.32":
|
||||
version "14.2.32"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.32.tgz#d1f1f854a1fbbaeefa8f81271437448653f33494"
|
||||
integrity sha512-jHUeDPVHrgFltqoAqDB6g6OStNnFxnc7Aks3p0KE0FbwAvRg6qWKYF5mSTdCTxA3axoSAUwxYdILzXJfUwlHhA==
|
||||
|
||||
"@next/swc-win32-x64-msvc@14.2.22":
|
||||
version "14.2.22"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.22.tgz#b034f544c1346093a235f6bba46497a1ba344fc1"
|
||||
integrity sha512-nvRaB1PyG4scn9/qNzlkwEwLzuoPH3Gjp7Q/pLuwUgOTt1oPMlnCI3A3rgkt+eZnU71emOiEv/mR201HoURPGg==
|
||||
"@next/swc-win32-x64-msvc@14.2.32":
|
||||
version "14.2.32"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.32.tgz#8212d681cf6858a9e3204728f8f2b161000683ed"
|
||||
integrity sha512-2N0lSoU4GjfLSO50wvKpMQgKd4HdI2UHEhQPPPnlgfBJlOgJxkjpkYBqzk08f1gItBB6xF/n+ykso2hgxuydsA==
|
||||
|
||||
"@nodelib/fs.scandir@2.1.5":
|
||||
version "2.1.5"
|
||||
@ -4571,13 +4603,6 @@ binary-extensions@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
||||
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
|
||||
|
||||
bindings@^1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"
|
||||
integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==
|
||||
dependencies:
|
||||
file-uri-to-path "1.0.0"
|
||||
|
||||
body-scroll-lock@^3.1.5:
|
||||
version "3.1.5"
|
||||
resolved "https://registry.yarnpkg.com/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz#c1392d9217ed2c3e237fee1e910f6cdd80b7aaec"
|
||||
@ -4731,12 +4756,7 @@ camelcase@^6.2.0:
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
|
||||
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
|
||||
|
||||
caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001503:
|
||||
version "1.0.30001503"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001503.tgz#88b6ff1b2cf735f1f3361dc1a15b59f0561aa398"
|
||||
integrity sha512-Sf9NiF+wZxPfzv8Z3iS0rXM1Do+iOy2Lxvib38glFX+08TCYYYGR5fRJXk4d77C4AYwhUjgYgMsMudbh2TqCKw==
|
||||
|
||||
caniuse-lite@^1.0.30001579:
|
||||
caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001503, caniuse-lite@^1.0.30001579:
|
||||
version "1.0.30001585"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001585.tgz#0b4e848d84919c783b2a41c13f7de8ce96744401"
|
||||
integrity sha512-yr2BWR1yLXQ8fMpdS/4ZZXpseBgE7o4g41x3a6AJOqZuOi+iE/WdJYAuZ6Y95i4Ohd2Y+9MzIWRR+uGABH4s3Q==
|
||||
@ -5083,25 +5103,24 @@ dc-polyfill@^0.1.4:
|
||||
resolved "https://registry.yarnpkg.com/dc-polyfill/-/dc-polyfill-0.1.4.tgz#4118cec81a8fab9a5729c41c285c715ffa42495a"
|
||||
integrity sha512-8iwEduR2jR9wWYggeaYtYZWRiUe3XZPyAQtMTL1otv8X3kfR8xUIVb4l5awHEeyDrH6Je7N324lKzMKlMMN6Yw==
|
||||
|
||||
dd-trace@^5.30.0:
|
||||
version "5.30.0"
|
||||
resolved "https://registry.yarnpkg.com/dd-trace/-/dd-trace-5.30.0.tgz#b81cf5f1e20822bee55bcb0dfe475578cea59faf"
|
||||
integrity sha512-rKNuh/uLgGw3CjpBK5TkhSX/2ErVTO2/b+FQlgKXJSx/h7GFD8AzGEj3VKKAm1ANLLLjFqS9+ulLmFhgtxXsPg==
|
||||
dd-trace@5.24.0:
|
||||
version "5.24.0"
|
||||
resolved "https://registry.yarnpkg.com/dd-trace/-/dd-trace-5.24.0.tgz#971fcb53edec4023619642a1716e063987bf0c00"
|
||||
integrity sha512-KJX/2ZRShuNafNaUkcWPwbIdq4bU1HQ0FrhPJWgKvljwAtNETeRhjac9nEe1fH2A9fTCGg5XCXifvK9Wr5g4xQ==
|
||||
dependencies:
|
||||
"@datadog/libdatadog" "^0.3.0"
|
||||
"@datadog/native-appsec" "8.3.0"
|
||||
"@datadog/native-iast-rewriter" "2.6.1"
|
||||
"@datadog/native-iast-taint-tracking" "3.2.0"
|
||||
"@datadog/native-metrics" "^3.1.0"
|
||||
"@datadog/pprof" "5.4.1"
|
||||
"@datadog/native-appsec" "8.1.1"
|
||||
"@datadog/native-iast-rewriter" "2.5.0"
|
||||
"@datadog/native-iast-taint-tracking" "3.1.0"
|
||||
"@datadog/native-metrics" "^2.0.0"
|
||||
"@datadog/pprof" "5.3.0"
|
||||
"@datadog/sketches-js" "^2.1.0"
|
||||
"@isaacs/ttlcache" "^1.4.1"
|
||||
"@opentelemetry/api" ">=1.0.0 <1.9.0"
|
||||
"@opentelemetry/core" "^1.14.0"
|
||||
crypto-randomuuid "^1.0.0"
|
||||
dc-polyfill "^0.1.4"
|
||||
ignore "^5.2.4"
|
||||
import-in-the-middle "1.11.2"
|
||||
int64-buffer "^0.1.9"
|
||||
istanbul-lib-coverage "3.2.0"
|
||||
jest-docblock "^29.7.0"
|
||||
koalas "^1.0.2"
|
||||
@ -5109,15 +5128,15 @@ dd-trace@^5.30.0:
|
||||
lodash.sortby "^4.7.0"
|
||||
lru-cache "^7.14.0"
|
||||
module-details-from-path "^1.0.3"
|
||||
msgpack-lite "^0.1.26"
|
||||
opentracing ">=0.12.1"
|
||||
path-to-regexp "^0.1.12"
|
||||
path-to-regexp "^0.1.10"
|
||||
pprof-format "^2.1.0"
|
||||
protobufjs "^7.2.5"
|
||||
retry "^0.13.1"
|
||||
rfdc "^1.3.1"
|
||||
semver "^7.5.4"
|
||||
shell-quote "^1.8.1"
|
||||
source-map "^0.7.4"
|
||||
tlhunter-sorted-set "^0.1.0"
|
||||
|
||||
debug@4, debug@4.3.4, debug@4.x, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4:
|
||||
@ -5510,14 +5529,6 @@ env-paths@^2.2.0:
|
||||
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
|
||||
integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
|
||||
|
||||
erlpack@0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/erlpack/-/erlpack-0.1.4.tgz#018758a53206b8e9ba1f6c58a6766e3ba261a113"
|
||||
integrity sha512-CJYbkEvsB5FqCCu2tLxF1eYKi28PvemC12oqzJ9oO6mDFrFO9G9G7nNJUHhiAyyL9zfXTOJx/tOcrQk+ncD65w==
|
||||
dependencies:
|
||||
bindings "^1.5.0"
|
||||
nan "^2.15.0"
|
||||
|
||||
err-code@^2.0.2:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9"
|
||||
@ -5865,6 +5876,11 @@ esutils@^2.0.2:
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||
|
||||
event-lite@^0.1.1:
|
||||
version "0.1.3"
|
||||
resolved "https://registry.yarnpkg.com/event-lite/-/event-lite-0.1.3.tgz#3dfe01144e808ac46448f0c19b4ab68e403a901d"
|
||||
integrity sha512-8qz9nOz5VeD2z96elrEKD2U433+L3DWdUdDkOINLGOJvx1GsMBbMn0aCeu28y8/e85A6mCigBiFlYMnTBEGlSw==
|
||||
|
||||
event-target-shim@^5.0.0:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
|
||||
@ -6025,11 +6041,6 @@ file-entry-cache@^6.0.1:
|
||||
dependencies:
|
||||
flat-cache "^3.0.4"
|
||||
|
||||
file-uri-to-path@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
|
||||
integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
|
||||
|
||||
filelist@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5"
|
||||
@ -6735,7 +6746,7 @@ idb@7.1.1, idb@^7.0.1:
|
||||
resolved "https://registry.yarnpkg.com/idb/-/idb-7.1.1.tgz#d910ded866d32c7ced9befc5bfdf36f572ced72b"
|
||||
integrity sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==
|
||||
|
||||
ieee754@^1.1.13:
|
||||
ieee754@^1.1.13, ieee754@^1.1.8:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||
@ -6828,6 +6839,11 @@ install-artifact-from-github@^1.3.3:
|
||||
resolved "https://registry.yarnpkg.com/install-artifact-from-github/-/install-artifact-from-github-1.3.3.tgz#57d89bacfa0f47d7307fe41b6247cda9f9a8079c"
|
||||
integrity sha512-x79SL0d8WOi1ZjXSTUqqs0GPQZ92YArJAN9O46wgU9wdH2U9ecyyhB9YGDbPe2OLV4ptmt6AZYRQZ2GydQZosQ==
|
||||
|
||||
int64-buffer@^0.1.9:
|
||||
version "0.1.10"
|
||||
resolved "https://registry.yarnpkg.com/int64-buffer/-/int64-buffer-0.1.10.tgz#277b228a87d95ad777d07c13832022406a473423"
|
||||
integrity sha512-v7cSY1J8ydZ0GyjUHqF+1bshJ6cnEVLo9EnjB8p+4HDRPZc9N5jjmvUV7NvEsqQOKyH0pmIBFWXVQbiS0+OBbA==
|
||||
|
||||
internal-slot@^1.0.3, internal-slot@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986"
|
||||
@ -7100,7 +7116,7 @@ is-wsl@^2.2.0:
|
||||
dependencies:
|
||||
is-docker "^2.0.0"
|
||||
|
||||
isarray@~1.0.0:
|
||||
isarray@^1.0.0, isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
|
||||
@ -8225,10 +8241,10 @@ mongodb@4.17.2:
|
||||
"@aws-sdk/credential-providers" "^3.186.0"
|
||||
"@mongodb-js/saslprep" "^1.1.0"
|
||||
|
||||
mongoose@6.13.5:
|
||||
version "6.13.5"
|
||||
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-6.13.5.tgz#33e628d259787221e8c6ecc740189896f35c7edc"
|
||||
integrity sha512-podJEaIF/5N2mQymkyyUzN2NeL/68MOyYjf3O0zsgCU2B2Omnhg6NhGHVavt9ZH/VxOrwKE9XphbuHDFK+T06g==
|
||||
mongoose@6.13.6:
|
||||
version "6.13.6"
|
||||
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-6.13.6.tgz#5f90f1bfd470a30a5fcb06e88bdc3ae47fbe6dd4"
|
||||
integrity sha512-1c5NBoiJ+n7wBVaifBsFVSnVkCB/m6IfnZh6ppnyQVLTtK99mS37nfW/ytnoftIcu1ITvRDgzgOj5H2fPX5ezw==
|
||||
dependencies:
|
||||
bson "^4.7.2"
|
||||
kareem "2.5.1"
|
||||
@ -8260,6 +8276,16 @@ ms@2.1.3, ms@^2.0.0, ms@^2.1.1:
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||
|
||||
msgpack-lite@^0.1.26:
|
||||
version "0.1.26"
|
||||
resolved "https://registry.yarnpkg.com/msgpack-lite/-/msgpack-lite-0.1.26.tgz#dd3c50b26f059f25e7edee3644418358e2a9ad89"
|
||||
integrity sha512-SZ2IxeqZ1oRFGo0xFGbvBJWMp3yLIY9rlIJyxy8CGrwZn1f0ZK4r6jV/AM1r0FZMDUkWkglOk/eeKIL9g77Nxw==
|
||||
dependencies:
|
||||
event-lite "^0.1.1"
|
||||
ieee754 "^1.1.8"
|
||||
int64-buffer "^0.1.9"
|
||||
isarray "^1.0.0"
|
||||
|
||||
mute-stream@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
|
||||
@ -8284,7 +8310,7 @@ mz@^2.7.0:
|
||||
object-assign "^4.0.1"
|
||||
thenify-all "^1.0.0"
|
||||
|
||||
nan@^2.15.0, nan@^2.17.0:
|
||||
nan@^2.17.0:
|
||||
version "2.17.0"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb"
|
||||
integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==
|
||||
@ -8338,12 +8364,12 @@ next-seo@^6.1.0:
|
||||
resolved "https://registry.yarnpkg.com/next-seo/-/next-seo-6.1.0.tgz#b60b06958cc77e7ed56f0a61b2d6cd0afed88ebb"
|
||||
integrity sha512-iMBpFoJsR5zWhguHJvsoBDxDSmdYTHtnVPB1ij+CD0NReQCP78ZxxbdL9qkKIf4oEuZEqZkrjAQLB0bkII7RYA==
|
||||
|
||||
next@^14.2.22:
|
||||
version "14.2.22"
|
||||
resolved "https://registry.yarnpkg.com/next/-/next-14.2.22.tgz#0cd664916ef4c725f31fa812d870348cffd0115b"
|
||||
integrity sha512-Ps2caobQ9hlEhscLPiPm3J3SYhfwfpMqzsoCMZGWxt9jBRK9hoBZj2A37i8joKhsyth2EuVKDVJCTF5/H4iEDw==
|
||||
next@^14.2.32:
|
||||
version "14.2.32"
|
||||
resolved "https://registry.yarnpkg.com/next/-/next-14.2.32.tgz#279b544f0c8ed023c33454ce4d563d3e05c2f3fb"
|
||||
integrity sha512-fg5g0GZ7/nFc09X8wLe6pNSU8cLWbLRG3TZzPJ1BJvi2s9m7eF991se67wliM9kR5yLHRkyGKU49MMx58s3LJg==
|
||||
dependencies:
|
||||
"@next/env" "14.2.22"
|
||||
"@next/env" "14.2.32"
|
||||
"@swc/helpers" "0.5.5"
|
||||
busboy "1.6.0"
|
||||
caniuse-lite "^1.0.30001579"
|
||||
@ -8351,15 +8377,15 @@ next@^14.2.22:
|
||||
postcss "8.4.31"
|
||||
styled-jsx "5.1.1"
|
||||
optionalDependencies:
|
||||
"@next/swc-darwin-arm64" "14.2.22"
|
||||
"@next/swc-darwin-x64" "14.2.22"
|
||||
"@next/swc-linux-arm64-gnu" "14.2.22"
|
||||
"@next/swc-linux-arm64-musl" "14.2.22"
|
||||
"@next/swc-linux-x64-gnu" "14.2.22"
|
||||
"@next/swc-linux-x64-musl" "14.2.22"
|
||||
"@next/swc-win32-arm64-msvc" "14.2.22"
|
||||
"@next/swc-win32-ia32-msvc" "14.2.22"
|
||||
"@next/swc-win32-x64-msvc" "14.2.22"
|
||||
"@next/swc-darwin-arm64" "14.2.32"
|
||||
"@next/swc-darwin-x64" "14.2.32"
|
||||
"@next/swc-linux-arm64-gnu" "14.2.32"
|
||||
"@next/swc-linux-arm64-musl" "14.2.32"
|
||||
"@next/swc-linux-x64-gnu" "14.2.32"
|
||||
"@next/swc-linux-x64-musl" "14.2.32"
|
||||
"@next/swc-win32-arm64-msvc" "14.2.32"
|
||||
"@next/swc-win32-ia32-msvc" "14.2.32"
|
||||
"@next/swc-win32-x64-msvc" "14.2.32"
|
||||
|
||||
node-addon-api@^6.1.0:
|
||||
version "6.1.0"
|
||||
@ -8391,9 +8417,9 @@ node-fetch@^2.6.9, node-fetch@^2.7.0:
|
||||
whatwg-url "^5.0.0"
|
||||
|
||||
node-forge@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3"
|
||||
integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.2.tgz#d0d2659a26eef778bf84d73e7f55c08144ee7750"
|
||||
integrity sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw==
|
||||
|
||||
node-gyp-build@<4.0, node-gyp-build@^3.9.0:
|
||||
version "3.9.0"
|
||||
@ -8763,7 +8789,7 @@ path-scurry@^1.7.0:
|
||||
lru-cache "^9.1.1"
|
||||
minipass "^5.0.0 || ^6.0.2"
|
||||
|
||||
path-to-regexp@^0.1.12:
|
||||
path-to-regexp@^0.1.10:
|
||||
version "0.1.12"
|
||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7"
|
||||
integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==
|
||||
@ -9520,10 +9546,10 @@ regenerate@^1.4.2:
|
||||
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a"
|
||||
integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==
|
||||
|
||||
regenerator-runtime@^0.13.11:
|
||||
version "0.13.11"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
|
||||
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
|
||||
regenerator-runtime@^0.14.0:
|
||||
version "0.14.1"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f"
|
||||
integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
|
||||
|
||||
regenerator-transform@^0.15.1:
|
||||
version "0.15.1"
|
||||
@ -10707,9 +10733,9 @@ undici-types@~6.20.0:
|
||||
integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==
|
||||
|
||||
undici@^5.22.1:
|
||||
version "5.28.5"
|
||||
resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.5.tgz#b2b94b6bf8f1d919bc5a6f31f2c01deb02e54d4b"
|
||||
integrity sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==
|
||||
version "5.29.0"
|
||||
resolved "https://registry.yarnpkg.com/undici/-/undici-5.29.0.tgz#419595449ae3f2cdcba3580a2e8903399bd1f5a3"
|
||||
integrity sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==
|
||||
dependencies:
|
||||
"@fastify/busboy" "^2.0.0"
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user