82 lines
2.3 KiB
JavaScript
82 lines
2.3 KiB
JavaScript
import cheerio from 'cheerio'
|
|
import got from 'got'
|
|
import { omitBy, isUndefined } from 'lodash-es'
|
|
|
|
export async function get(
|
|
route,
|
|
{
|
|
method = 'get',
|
|
body,
|
|
followRedirects = false,
|
|
followAllRedirects = false,
|
|
headers,
|
|
responseType,
|
|
retries = 0,
|
|
} = {},
|
|
) {
|
|
const fn = got[method]
|
|
if (!fn || typeof fn !== 'function') throw new Error(`No method function for '${method}'`)
|
|
const xopts = omitBy(
|
|
{
|
|
body,
|
|
headers,
|
|
retry: { limit: retries },
|
|
throwHttpErrors: false,
|
|
followRedirect: followAllRedirects || followRedirects,
|
|
responseType,
|
|
},
|
|
isUndefined,
|
|
)
|
|
return await fn(`http://localhost:4000${route}`, xopts)
|
|
}
|
|
|
|
export async function head(route, opts = { followRedirects: false }) {
|
|
const res = await get(route, { method: 'head', followRedirects: opts.followRedirects })
|
|
return res
|
|
}
|
|
|
|
export function post(route, opts) {
|
|
return get(route, Object.assign({}, opts, { method: 'post' }))
|
|
}
|
|
|
|
const getDOMCache = new Map()
|
|
|
|
export async function getDOMCached(route, options) {
|
|
// got() can take a `cache` option but it's slower than just doing
|
|
// a simple memoization pattern.
|
|
const key = `${route}::${JSON.stringify(options)}`
|
|
if (!getDOMCache.has(key)) {
|
|
getDOMCache.set(key, await getDOM(route, options))
|
|
}
|
|
return getDOMCache.get(key)
|
|
}
|
|
|
|
export async function getDOM(
|
|
route,
|
|
{ headers, allow500s = false, allow404 = false, retries = 0 } = {},
|
|
) {
|
|
const res = await get(route, { followRedirects: true, headers, retries })
|
|
if (!allow500s && res.statusCode >= 500) {
|
|
throw new Error(`Server error (${res.statusCode}) on ${route}`)
|
|
}
|
|
if (!allow404 && res.statusCode === 404) {
|
|
throw new Error(`Page not found on ${route} (${res.statusCode})`)
|
|
}
|
|
const $ = cheerio.load(res.body || '', { xmlMode: true })
|
|
$.res = Object.assign({}, res)
|
|
return $
|
|
}
|
|
|
|
// For use with the ?json query param
|
|
// e.g. await getJSON('/en?json=breadcrumbs')
|
|
export async function getJSON(route, opts) {
|
|
const res = await get(route, { ...opts, followRedirects: true })
|
|
if (res.statusCode >= 500) {
|
|
throw new Error(`Server error (${res.statusCode}) on ${route}`)
|
|
}
|
|
if (res.statusCode >= 400) {
|
|
console.warn(`${res.statusCode} on ${route} and the response might not be JSON`)
|
|
}
|
|
return JSON.parse(res.body)
|
|
}
|