Files
mocoapp-browser-extension/src/js/utils/urlMatcher.js
2019-03-26 10:01:58 +01:00

105 lines
2.2 KiB
JavaScript

import UrlPattern from "url-pattern"
import {
isFunction,
isUndefined,
compose,
toPairs,
map,
pipe
} from "lodash/fp"
import queryString from "query-string"
const extractQueryParams = (queryParams, query) => {
return toPairs(queryParams).reduce((acc, [key, param]) => {
acc[key] = query[param]
return acc
}, {})
}
const createEvaluator = args => fnOrValue => {
if (isUndefined(fnOrValue)) {
return
}
if (isFunction(fnOrValue)) {
return fnOrValue(...args)
}
return fnOrValue
}
const parseServices = compose(
map(([key, config]) => ({
...config,
key,
patterns: config.urlPatterns.map(pattern => {
if (Array.isArray(pattern)) {
return new UrlPattern(...pattern)
}
return new UrlPattern(pattern)
})
})),
toPairs
)
export const createEnhancer = document => service => {
if (!service) {
return
}
const match = service.match
const args = [document, service, match]
const evaluate = createEvaluator(args)
return {
...service,
id: evaluate(service.id),
description: evaluate(service.description),
projectId: evaluate(service.projectId),
taskId: evaluate(service.taskId),
position: service.position || { right: "calc(2rem + 5px)" }
}
}
export const createMatcher = remoteServices => {
const services = parseServices(remoteServices)
return tabUrl => {
const { origin, pathname, hash, search } = new URL(tabUrl)
const url = `${origin}${pathname}${hash}`
const query = queryString.parse(search)
const service = services.find(service =>
service.patterns.some(pattern => pattern.match(url))
)
if (!service) {
return
}
const pattern = service.patterns.find(pattern => pattern.match(url))
let match = pattern.match(url)
if (service.queryParams) {
const extractedQueryParams = extractQueryParams(
service.queryParams,
query
)
match = { ...extractedQueryParams, ...match }
}
return {
...match,
...service,
url,
match
}
}
}
export const createServiceFinder = remoteServices => document => {
const matcher = createMatcher(remoteServices)
const enhancer = createEnhancer(document)
return pipe(
matcher,
enhancer
)
}