105 lines
2.2 KiB
JavaScript
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
|
|
)
|
|
}
|