|
|
import { FastifyInstance, RouteShorthandOptions, Plugin, DefaultQuery, DefaultParams, DefaultHeaders, DefaultBody, JSONSchema, } from 'fastify' import { Server, IncomingMessage, ServerResponse } from 'http' import request from 'request' import { PluginOptions, GiphyResponse } from '../../types'
interface FetchOptions { url: string params?: string[][] method?: string }
const paramsToString = (params: string[][]) => params.map(p => p.join('=')).join('&')
const giphyGifSchema: JSONSchema = { type: 'object', properties: { type: { type: 'string' }, id: { type: 'string' }, slug: { type: 'string' }, url: { type: 'string' }, bitly_url: { type: 'string' }, embed_url: { type: 'string' }, title: { type: 'string' }, images: { type: 'object', properties: { fixed_height: { type: 'object', properties: { url: { type: 'string' }, }, }, fixed_height_still: { type: 'object', properties: { url: { type: 'string' }, }, }, fixed_height_downsampled: { type: 'object', properties: { url: { type: 'string' }, }, }, }, }, }, }
async function fetch<T = any>(options: FetchOptions) { const { url, params = [], method = 'get' } = options const uri = params.length > 0 ? `${url}?${paramsToString(params)}` : url
return new Promise<T>((resolve, reject) => { request({ uri, method, json: true, }, function(error, response, body) { if (error) { reject(error) return }
resolve(body) }) }) }
function gifHomeRoute(server: FastifyInstance<Server, IncomingMessage, ServerResponse>) { const options: RouteShorthandOptions = { schema: { response: { 200: { type: 'array', items: giphyGifSchema, }, }, }, }
server.get<DefaultQuery, DefaultParams, DefaultHeaders, DefaultBody>('/api/gifs/home', options, async (request, reply) => { const response = await fetch<GiphyResponse>({ url: `${process.env.GIPHY_API_ENDPOINT!}/v1/gifs/trending`, params: [['api_key', process.env.GIPHY_API_KEY!], ['limit', '20']], })
return response.data }) }
function gifSearchRoute(server: FastifyInstance<Server, IncomingMessage, ServerResponse>) { interface Query { q: string }
const options: RouteShorthandOptions = { schema: { querystring: { type: 'object', properties: { q: { type: 'string' }, }, }, response: { 200: { type: 'array', items: giphyGifSchema, }, }, }, }
server.get<Query, DefaultParams, DefaultHeaders, DefaultBody>('/api/gifs/search', options, async (request, reply) => { const q = request.query.q ? request.query.q.trim() : ''
if (q.length < 3) { reply.code(400) return }
const response = await fetch<GiphyResponse>({ url: `${process.env.GIPHY_API_ENDPOINT!}/v1/gifs/search`, params: [['api_key', process.env.GIPHY_API_KEY!], ['limit', '20'], ['q', q]], })
return response.data }) }
const plugin: Plugin<Server, IncomingMessage, ServerResponse, PluginOptions> = async server => { gifHomeRoute(server) gifSearchRoute(server) }
export default plugin
|