Skip to content

Commit

Permalink
fix: avoid unnecessary avatar URL calls
Browse files Browse the repository at this point in the history
  • Loading branch information
Kikobeats committed Jul 16, 2021
1 parent 7ea78e8 commit a8c7bef
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 30 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@
"memoize-one": "~5.2.1",
"morgan": "~1.10.0",
"p-any": "~3.0.0",
"p-map": "~4.0.0",
"p-reflect": "~2.1.0",
"p-timeout": "~4.1.0",
"qsm": "~2.1.2",
Expand Down
46 changes: 17 additions & 29 deletions src/avatar-url.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict'

const { omit, eq, get, isNil, compact } = require('lodash')
const { omit, eq, get, isNil } = require('lodash')
const debug = require('debug-logfmt')('unavatar')
const isAbsoluteUrl = require('is-absolute-url')
const reachableUrl = require('reachable-url')
Expand All @@ -13,7 +13,6 @@ const pTimeout = require('p-timeout')
const urlRegex = require('url-regex')
const pReflect = require('p-reflect')
const pAny = require('p-any')
const pMap = require('p-map')

const { isReachable } = reachableUrl

Expand Down Expand Up @@ -44,40 +43,29 @@ const getFallbackUrl = memoizeOne(({ query, protocol, host }) => {
: getDefaultFallbackUrl({ protocol, host })
})

const is = str => {
if (isEmail(str)) return 'email'
if (urlRegex({ strict: false }).test(str)) return 'domain'
const is = input => {
if (isEmail(input)) return 'email'
if (urlRegex({ strict: false }).test(input)) return 'domain'
return 'username'
}

const getAvatarUrl = async key => {
const collection = get(providersBy, is(key))

// get all the urls from the providers that can resolve the key
const urls = compact(
await pMap(collection, async provider => {
try {
const urlFn = get(providers, provider)
const url = await pTimeout(urlFn(key), AVATAR_TIMEOUT)
return isAbsoluteUrl(url) ? url : null
} catch (err) {
return null
}
})
)
const getAvatarUrl = async (fn, input) => {
const avatarUrl = await fn(input)
if (!isAbsoluteUrl(avatarUrl)) throw new Error('Avatar URL is not valid.')
const { statusCode, url } = await reachableUrl(avatarUrl)
if (!isReachable({ statusCode })) throw new Error('Avatar URL is not reachable.')
return url
}

// get the first request in resolve the ping successfully
const avatarUrl = await pAny(
urls.map(async targetUrl => {
const { statusCode, url } = await reachableUrl(targetUrl)
return isReachable({ statusCode }) ? url : undefined
})
const getFirstReachableAvatarUrl = async input => {
const collection = get(providersBy, is(input))
const promises = collection.map(providerName =>
pTimeout(getAvatarUrl(get(providers, providerName), input), AVATAR_TIMEOUT)
)

return avatarUrl
return pAny(promises)
}

module.exports = (fn = getAvatarUrl) => async (req, res) => {
module.exports = (fn = getFirstReachableAvatarUrl) => async (req, res) => {
const { query, protocol } = req
const host = req.get('host')
const input = get(req, 'params.key')
Expand Down

1 comment on commit a8c7bef

@vercel
Copy link

@vercel vercel bot commented on a8c7bef Jul 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.