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(options: FetchOptions) { const { url, params = [], method = 'get' } = options const uri = params.length > 0 ? `${url}?${paramsToString(params)}` : url return new Promise((resolve, reject) => { request({ uri, method, json: true, }, function(error, response, body) { if (error) { reject(error) return } resolve(body) }) }) } function gifHomeRoute(server: FastifyInstance) { const options: RouteShorthandOptions = { schema: { response: { 200: { type: 'array', items: giphyGifSchema, }, }, }, } server.get('/api/gifs/home', options, async (request, reply) => { const response = await fetch({ 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) { interface Query { q: string } const options: RouteShorthandOptions = { schema: { querystring: { type: 'object', properties: { q: { type: 'string' }, }, }, response: { 200: { type: 'array', items: giphyGifSchema, }, }, }, } server.get('/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({ 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 = async server => { gifHomeRoute(server) gifSearchRoute(server) } export default plugin