Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use mql as fetcher #162

Merged
merged 13 commits into from
Oct 14, 2019
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,8 @@
"standard-markdown",
"git add"
]
},
"dependencies": {
"@microlink/mql": "~0.5.0"
}
}
12 changes: 6 additions & 6 deletions packages/react/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { CardWrap, CardMedia, CardContent, CardEmpty } from './components/Card'
import {
defaultApiParameters,
isNil,
createApiUrl,
fetchFromApiUrl,
getApiUrl,
fetchFromApi,
getUrlPath,
imageProxy,
someProp,
Expand Down Expand Up @@ -51,7 +51,7 @@ function Microlink (props) {
isLoadingUndefined ? true : loadingProp
)
const [cardData, setCardData] = useState({})
const apiUrl = useMemo(() => createApiUrl(props), [props])
const [apiUrl, apiUrlProps] = useMemo(() => getApiUrl(props), [props])
Copy link
Member Author

@Kikobeats Kikobeats Oct 8, 2019

Choose a reason for hiding this comment

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

getApiUrl is returning two tings:

  • apiUrl (string): The API url for doing the GET request.
  • apiUrlProps (object): some options to be pass to fetch (like headers, etc).

Since this is directly used by useCallback props, I'm not sure if the best thing here is to split them into two different things (the current approach) or pass it as a whole thing, like:

const apiUrlProps = useMemo(() => getApiUrl(props), [props])

// passing it to fetcher
fetchFromApi(props.url, ...apiUrlProps)

// later, on props over `useCallback`
[canFetchData, setData, ...apiUrlProps])

thoughts? 🤔


const isLazyEnabled = useMemo(
() => isLazySupported && (lazy === true || isObject(lazy)),
Expand All @@ -73,11 +73,11 @@ function Microlink (props) {
setLoading(true)
const fetch = isFunction(setData)
? Promise.resolve({})
: fetchFromApiUrl(apiUrl, props.apiKey)
: fetchFromApi(props.url, apiUrl, apiUrlProps)

fetch.then(({ data }) => mergeData(data))
}
}, [apiUrl, canFetchData, setData, props.apiKey])
}, [apiUrl, canFetchData, setData, apiUrlProps])

const mergeData = useCallback(
fetchData => {
Expand Down Expand Up @@ -202,6 +202,6 @@ Microlink.propTypes = {
url: PropTypes.string
}

export { imageProxy, createApiUrl, fetchFromApiUrl }
export { imageProxy, getApiUrl, fetchFromApi }

export default Microlink
65 changes: 20 additions & 45 deletions packages/react/src/utils/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* global fetch */

import { css } from 'styled-components'
import mql from '@microlink/mql'

const REGEX_HTTPS = /^https/
const REGEX_LOCALHOST = /http:\/\/localhost/
Expand Down Expand Up @@ -31,56 +30,32 @@ export const media = {
`
}

const apiValue = (key, value) => (value === true ? `${key}` : `${key}=${value}`)

export const defaultApiParameters = {
contrast: false,
prerender: 'auto',
screenshot: false,
video: false
}

export const createApiUrl = props => {
const { apiKey, url: targetUrl, prerender, contrast, media } = props
const takeScreenshot = media.includes('screenshot')
const hasVideo = media.includes('video')

const alias = apiKey ? 'pro' : 'api'
let url = `https://${alias}.microlink.io/?url=${encodeURIComponent(
targetUrl
)}`

if (hasVideo) {
url = `${url}&${apiValue('video', hasVideo)}`
}

if (!isNil(contrast) && contrast !== defaultApiParameters.contrast) {
url = `${url}&${apiValue('palette', contrast)}`
}

if (!isNil(prerender) && prerender !== defaultApiParameters.prerender) {
url = `${url}&${apiValue('prerender', prerender)}`
}

if (takeScreenshot) {
url = `${url}&${apiValue('screenshot', takeScreenshot)}`
}

return url
}

export const fetchFromApiUrl = (apiUrl, apiKey) => {
const headers = apiKey ? { 'x-api-key': apiKey } : {}
return fetch(apiUrl, { headers }).then(res => res.json())
}
export const getApiUrl = ({
apiKey,
url,
prerender = 'auto',
contrast = false,
media,
...opts
}) =>
mql.getApiUrl(url, {
apiKey,
video: media.includes('video'),
screenshot: media.includes('screenshot'),
palette: contrast,
prerender,
...opts
})

export const fetchFromApi = mql.fetchFromApi

export const isLarge = cardSize => cardSize === 'large'

export const isSmall = cardSize => cardSize === 'small'

export const imageProxy = url => {
if (!url || REGEX_LOCALHOST.test(url) || REGEX_HTTPS.test(url)) return url
return `https://images.weserv.nl/?url=${encodeURIComponent(url).replace(
return `https://images.weserv.nl/?url=${encodeURI(url).replace(
'http://',
''
)}`
Expand Down