diff --git a/pages/api/[...404].ts b/pages/api/[...404].ts index 1ffb88f..8fb18bd 100644 --- a/pages/api/[...404].ts +++ b/pages/api/[...404].ts @@ -1,9 +1,7 @@ -import { NextApiRequest, NextApiResponse } from 'next' -import nc from 'next-connect' - import ResponseWrapper from '@utils/ResponseWrapper' +import RequestHandler from '@utils/RequestHandler' -const NotFound = nc() +const NotFound = RequestHandler .all(async(_req, res) => { return ResponseWrapper(res, { code: 404, message: '요청하신 URL에 페이지가 존재하지 않습니다.' }) }) diff --git a/pages/api/auth/discord/callback.ts b/pages/api/auth/discord/callback.ts index 998920f..b423244 100644 --- a/pages/api/auth/discord/callback.ts +++ b/pages/api/auth/discord/callback.ts @@ -1,5 +1,4 @@ -import { NextApiRequest, NextApiResponse } from 'next' -import nc from 'next-connect' +import { NextApiRequest } from 'next' import fetch from 'node-fetch' import { serialize } from 'cookie' @@ -10,9 +9,10 @@ import ResponseWrapper from '@utils/ResponseWrapper' import { DiscordTokenInfo, DiscordUserInfo } from '@types' import { update } from '@utils/Query' import { verify } from '@utils/Jwt' +import RequestHandler from '@utils/RequestHandler' -const Callback = nc() - .get(async(req, res) => { +const Callback = RequestHandler + .get(async(req: ApiRequest, res) => { const validate = await OauthCallbackSchema.validate(req.query).then(r=> r).catch((e) => { ResponseWrapper(res, { code: 400, errors: e.errors }) return null diff --git a/pages/api/auth/discord/index.ts b/pages/api/auth/discord/index.ts index 3ebe620..37e39b6 100644 --- a/pages/api/auth/discord/index.ts +++ b/pages/api/auth/discord/index.ts @@ -1,8 +1,10 @@ -import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next' +import { NextApiRequest, NextApiResponse } from 'next' import { generateOauthURL } from '@utils/Tools' +import RequestHandler from '@utils/RequestHandler' -const Discord: NextApiHandler = (_req: NextApiRequest, res: NextApiResponse) => { - res.redirect(301, generateOauthURL('discord', process.env.DISCORD_CLIENT_ID, process.env.DISCORD_SCOPE)) -} +const Discord = RequestHandler + .get(async (_req: NextApiRequest, res: NextApiResponse) => { + res.redirect(301, generateOauthURL('discord', process.env.DISCORD_CLIENT_ID, process.env.DISCORD_SCOPE)) + }) export default Discord diff --git a/pages/api/auth/discord/logout.ts b/pages/api/auth/discord/logout.ts index 3ddc20b..ef0f3cc 100644 --- a/pages/api/auth/discord/logout.ts +++ b/pages/api/auth/discord/logout.ts @@ -1,9 +1,8 @@ -import { NextApiRequest, NextApiResponse } from 'next' -import nc from 'next-connect' import { serialize } from 'cookie' +import RequestHandler from '@utils/RequestHandler' -const Logout = nc() +const Logout = RequestHandler .get(async(req, res) => { res.setHeader('Cache-control', 'no-cache') res.setHeader('set-cookie', serialize('token', '', { diff --git a/pages/api/image/discord/avatars/[id].ts b/pages/api/image/discord/avatars/[id].ts index 979eae6..9289f26 100644 --- a/pages/api/image/discord/avatars/[id].ts +++ b/pages/api/image/discord/avatars/[id].ts @@ -1,14 +1,14 @@ -import { NextApiRequest, NextApiResponse } from 'next' -import nc from 'next-connect' +import { NextApiRequest } from 'next' import ResponseWrapper from '@utils/ResponseWrapper' import { DiscordEnpoints } from '@utils/Constants' import { get, ratelimit } from '@utils/Query' import RateLimitHandler from '@utils/RateLimitHandler' import { ImageOptionsSchema } from '@utils/Yup' +import RequestHandler from '@utils/RequestHandler' -const Avatar = nc() - .get(async(req, res) => { +const Avatar = RequestHandler + .get(async(req: ApiRequest, res) => { res.setHeader('Access-Control-Allow-Origin', process.env.KOREANBOTS_URL) const { imageRateLimit } = await import('@utils/Query') const { id: param, size='256' } = req.query diff --git a/pages/api/index.ts b/pages/api/index.ts index 94d76ee..a433928 100644 --- a/pages/api/index.ts +++ b/pages/api/index.ts @@ -1,10 +1,8 @@ -import { NextApiRequest, NextApiResponse } from 'next' -import nc from 'next-connect' - import ResponseWrapper from '@utils/ResponseWrapper' import { getMainGuild } from '@utils/DiscordBot' +import RequestHandler from '@utils/RequestHandler' -const HelloWorld = nc() +const HelloWorld = RequestHandler .get(async(_req, res) => { getMainGuild() // Load Discord Bot return ResponseWrapper(res, { code: 200, message: '>_<' }) diff --git a/pages/api/v1/[[...deprecated]].ts b/pages/api/v1/[[...deprecated]].ts index b1a23e7..98acdb7 100644 --- a/pages/api/v1/[[...deprecated]].ts +++ b/pages/api/v1/[[...deprecated]].ts @@ -1,12 +1,13 @@ -import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next' import ResponseWrapper from '@utils/ResponseWrapper' +import RequestHandler from '@utils/RequestHandler' -const Deprecated: NextApiHandler = (_req: NextApiRequest, res: NextApiResponse) => { - return ResponseWrapper(res, { - code: 406, - message: '해당 API 버전은 지원 종료되었습니다.', - version: 1, +const Deprecated = RequestHandler + .get(async (_req, res) => { + return ResponseWrapper(res, { + code: 406, + message: '해당 API 버전은 지원 종료되었습니다.', + version: 1, + }) }) -} export default Deprecated diff --git a/pages/api/v2/bots/[id].ts b/pages/api/v2/bots/[id].ts index abacf55..5f0f93d 100644 --- a/pages/api/v2/bots/[id].ts +++ b/pages/api/v2/bots/[id].ts @@ -1,18 +1,18 @@ -import { NextApiRequest, NextApiResponse } from 'next' -import nc from 'next-connect' +import { NextApiRequest } from 'next' import { get, put } from '@utils/Query' import ResponseWrapper from '@utils/ResponseWrapper' import { checkToken } from '@utils/Csrf' import { AddBotSubmit, AddBotSubmitSchema } from '@utils/Yup' +import RequestHandler from '@utils/RequestHandler' -const Bots = nc() - .get(async(req, res) => { +const Bots = RequestHandler + .get(async(req: GetApiRequest, res) => { const bot = await get.bot.load(req.query.id) if(!bot) return ResponseWrapper(res, { code: 404, message: '존재하지 않는 봇입니다.' }) else return ResponseWrapper(res, { code: 200, data: bot }) }) - .post(async (req, res) => { + .post(async (req: PostApiRequest, res) => { const user = await get.Authorization(req.cookies.token) if(!user) return ResponseWrapper(res, { code: 401 }) const csrfValidated = checkToken(req, res, req.body._csrf) @@ -36,7 +36,13 @@ const Bots = nc() return res.send('Reserved') }) -interface ApiRequest extends NextApiRequest { +interface GetApiRequest extends NextApiRequest { + query: { + id: string + } +} + +interface PostApiRequest extends GetApiRequest { body: AddBotSubmit | null query: { id: string diff --git a/pages/api/v2/search/bots.ts b/pages/api/v2/search/bots.ts index 697123b..1b109c2 100644 --- a/pages/api/v2/search/bots.ts +++ b/pages/api/v2/search/bots.ts @@ -1,24 +1,28 @@ -import { BotList } from '@types' +import { NextApiRequest, NextApiResponse } from 'next' + import { get } from '@utils/Query' +import RequestHandler from '@utils/RequestHandler' import ResponseWrapper from '@utils/ResponseWrapper' import { SearchQuerySchema } from '@utils/Yup' -import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next' -const SearchBots: NextApiHandler = async (req: ApiRequest, res: NextApiResponse) => { - const validated = await SearchQuerySchema.validate({ q: req.query.q, page: req.query.page }).then(el => el).catch(e => { - ResponseWrapper(res, { code: 400, errors: e.errors }) +import { BotList } from '@types' + +const SearchBots = RequestHandler + .get(async (req: ApiRequest, res: NextApiResponse) => { + const validated = await SearchQuerySchema.validate({ q: req.query.q, page: req.query.page }).then(el => el).catch(e => { + ResponseWrapper(res, { code: 400, errors: e.errors }) + }) + if(!validated) return + + let result: BotList + try { + result = await get.list.search.load(JSON.stringify({ page: validated.page, query: validated.q })) + } catch { + return ResponseWrapper(res, { code: 400, message: '검색 문법이 잘못되었습니다.' }) + } + if(result.totalPage < validated.page || result.currentPage !== validated.page) return ResponseWrapper(res, { code: 404, message: '검색 결과가 없습니다.' }) + else ResponseWrapper(res, { code: 200, data: result }) }) - if(!validated) return - - let result: BotList - try { - result = await get.list.search.load(JSON.stringify({ page: validated.page, query: validated.q })) - } catch { - return ResponseWrapper(res, { code: 400, message: '검색 문법이 잘못되었습니다.' }) - } - if(result.totalPage < validated.page || result.currentPage !== validated.page) return ResponseWrapper(res, { code: 404, message: '검색 결과가 없습니다.' }) - else ResponseWrapper(res, { code: 200, data: result }) -} interface ApiRequest extends NextApiRequest { query: { diff --git a/pages/api/v2/users/[id].ts b/pages/api/v2/users/[id].ts index 99a4194..24e9750 100644 --- a/pages/api/v2/users/[id].ts +++ b/pages/api/v2/users/[id].ts @@ -1,11 +1,11 @@ +import { NextApiRequest } from 'next' + import { get } from '@utils/Query' -import { NextApiRequest, NextApiResponse } from 'next' -import nc from 'next-connect' - import ResponseWrapper from '@utils/ResponseWrapper' +import RequestHandler from '@utils/RequestHandler' -const Users = nc() - .get(async(req, res) => { +const Users = RequestHandler + .get(async(req: ApiRequest, res) => { console.log(req.query) const user = await get.user.load(req.query?.id) if(!user) return ResponseWrapper(res, { code: 404, message: '존재하지 않는 유저 입니다.' }) diff --git a/pages/api/widget/bots/[type]/[id].ts b/pages/api/widget/bots/[type]/[id].ts index 64e5c4f..97f255f 100644 --- a/pages/api/widget/bots/[type]/[id].ts +++ b/pages/api/widget/bots/[type]/[id].ts @@ -1,4 +1,4 @@ -import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next' +import { NextApiRequest, NextApiResponse } from 'next' import ResponseWrapper from '@utils/ResponseWrapper' import { WidgetOptionsSchema } from '@utils/Yup' @@ -6,41 +6,43 @@ import { WidgetOptionsSchema } from '@utils/Yup' import { badgen } from 'badgen' import { get } from '@utils/Query' import { BotBadgeType, DiscordEnpoints } from '@utils/Constants' +import RequestHandler from '@utils/RequestHandler' -const Widget: NextApiHandler = async(req: ApiRequest, res: NextApiResponse) => { - const { id: param, type, style='flat', scale=1, icon=true } = req.query - const splitted = param.split('.') +const Widget= RequestHandler + .get(async(req: ApiRequest, res: NextApiResponse) => { + const { id: param, type, style='flat', scale=1, icon=true } = req.query + const splitted = param.split('.') - const validated = await WidgetOptionsSchema.validate({ - id: splitted.slice(0, splitted.length - 1).join('.'), - ext: splitted[splitted.length - 1], - style, - type, - scale, - icon - }).then(el=> el).catch(e=> { - ResponseWrapper(res, { code: 400, errors: e.errors }) - return null - }) + const validated = await WidgetOptionsSchema.validate({ + id: splitted.slice(0, splitted.length - 1).join('.'), + ext: splitted[splitted.length - 1], + style, + type, + scale, + icon + }).then(el=> el).catch(e=> { + ResponseWrapper(res, { code: 400, errors: e.errors }) + return null + }) - if(!validated) return + if(!validated) return - const data = await get.bot.load(validated.id) + const data = await get.bot.load(validated.id) - if(!data) return ResponseWrapper(res, { code: 404, message: '존재하지 않는 봇입니다.' }) - const userImage = !data.avatar ? null : await get.images.user.load(DiscordEnpoints.CDN.user(data.id, data.avatar, { format: 'png', size: 128 })) - const img = userImage || await get.images.user.load(DiscordEnpoints.CDN.default(data.tag, { format: 'png', size: 128 })) - res.setHeader('content-type', 'image/svg+xml; charset=utf-8') - const badgeData = { - ...BotBadgeType(data)[type], - style: validated.style, - scale: validated.scale, - icon: validated.icon ? `data:image/png;base64,${img.toString('base64')}` : null - } + if(!data) return ResponseWrapper(res, { code: 404, message: '존재하지 않는 봇입니다.' }) + const userImage = !data.avatar ? null : await get.images.user.load(DiscordEnpoints.CDN.user(data.id, data.avatar, { format: 'png', size: 128 })) + const img = userImage || await get.images.user.load(DiscordEnpoints.CDN.default(data.tag, { format: 'png', size: 128 })) + res.setHeader('content-type', 'image/svg+xml; charset=utf-8') + const badgeData = { + ...BotBadgeType(data)[type], + style: validated.style, + scale: validated.scale, + icon: validated.icon ? `data:image/png;base64,${img.toString('base64')}` : null + } - res.send(badgen(badgeData)) + res.send(badgen(badgeData)) -} + }) interface ApiRequest extends NextApiRequest { query: { diff --git a/utils/RequestHandler.ts b/utils/RequestHandler.ts new file mode 100644 index 0000000..af33934 --- /dev/null +++ b/utils/RequestHandler.ts @@ -0,0 +1,15 @@ +import { NextApiRequest, NextApiResponse } from 'next' +import nc from 'next-connect' +import ResponseWrapper from '@utils/ResponseWrapper' + +const RequestHandler = nc({ + onNoMatch(_req, res) { + return ResponseWrapper(res, { code: 405 }) + }, + onError(err, _req, res) { + console.error(err) + return ResponseWrapper(res, { code: 500 }) + } +}) + +export default RequestHandler \ No newline at end of file