94 lines
2.2 KiB
JavaScript
94 lines
2.2 KiB
JavaScript
|
import { match } from "@reach/router/lib/utils"
|
||
|
import stripPrefix from "./strip-prefix"
|
||
|
import normalizePagePath from "./normalize-page-path"
|
||
|
|
||
|
const pathCache = new Map()
|
||
|
let matchPaths = []
|
||
|
|
||
|
const trimPathname = rawPathname => {
|
||
|
const pathname = decodeURIComponent(rawPathname)
|
||
|
// Remove the pathPrefix from the pathname.
|
||
|
const trimmedPathname = stripPrefix(pathname, __BASE_PATH__)
|
||
|
// Remove any hashfragment
|
||
|
.split(`#`)[0]
|
||
|
// Remove search query
|
||
|
.split(`?`)[0]
|
||
|
|
||
|
return trimmedPathname
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set list of matchPaths
|
||
|
*
|
||
|
* @param {Array<{path: string, matchPath: string}>} value collection of matchPaths
|
||
|
*/
|
||
|
export const setMatchPaths = value => {
|
||
|
matchPaths = value
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return a matchpath url
|
||
|
* if `match-paths.json` contains `{ "/foo*": "/page1", ...}`, then
|
||
|
* `/foo?bar=far` => `/page1`
|
||
|
*
|
||
|
* @param {string} rawPathname A raw pathname
|
||
|
* @return {string|null}
|
||
|
*/
|
||
|
export const findMatchPath = rawPathname => {
|
||
|
const trimmedPathname = cleanPath(rawPathname)
|
||
|
|
||
|
for (const { matchPath, path } of matchPaths) {
|
||
|
if (match(matchPath, trimmedPathname)) {
|
||
|
return normalizePagePath(path)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return null
|
||
|
}
|
||
|
|
||
|
// Given a raw URL path, returns the cleaned version of it (trim off
|
||
|
// `#` and query params), or if it matches an entry in
|
||
|
// `match-paths.json`, its matched path is returned
|
||
|
//
|
||
|
// E.g. `/foo?bar=far` => `/foo`
|
||
|
//
|
||
|
// Or if `match-paths.json` contains `{ "/foo*": "/page1", ...}`, then
|
||
|
// `/foo?bar=far` => `/page1`
|
||
|
export const findPath = rawPathname => {
|
||
|
const trimmedPathname = trimPathname(rawPathname)
|
||
|
|
||
|
if (pathCache.has(trimmedPathname)) {
|
||
|
return pathCache.get(trimmedPathname)
|
||
|
}
|
||
|
|
||
|
let foundPath = findMatchPath(trimmedPathname)
|
||
|
|
||
|
if (!foundPath) {
|
||
|
foundPath = cleanPath(rawPathname)
|
||
|
}
|
||
|
|
||
|
pathCache.set(trimmedPathname, foundPath)
|
||
|
|
||
|
return foundPath
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Clean a url and converts /index.html => /
|
||
|
* E.g. `/foo?bar=far` => `/foo`
|
||
|
*
|
||
|
* @param {string} rawPathname A raw pathname
|
||
|
* @return {string}
|
||
|
*/
|
||
|
export const cleanPath = rawPathname => {
|
||
|
const trimmedPathname = trimPathname(rawPathname)
|
||
|
|
||
|
let foundPath = trimmedPathname
|
||
|
if (foundPath === `/index.html`) {
|
||
|
foundPath = `/`
|
||
|
}
|
||
|
|
||
|
foundPath = normalizePagePath(foundPath)
|
||
|
|
||
|
return foundPath
|
||
|
}
|