UNPKG

2.25 kBJavaScriptView Raw
1import { match } from "@reach/router/lib/utils"
2import stripPrefix from "./strip-prefix"
3import normalizePagePath from "./normalize-page-path"
4
5const pathCache = new Map()
6let matchPaths = []
7
8const trimPathname = rawPathname => {
9 const pathname = decodeURIComponent(rawPathname)
10 // Remove the pathPrefix from the pathname.
11 const trimmedPathname = stripPrefix(pathname, __BASE_PATH__)
12 // Remove any hashfragment
13 .split(`#`)[0]
14 // Remove search query
15 .split(`?`)[0]
16
17 return trimmedPathname
18}
19
20/**
21 * Set list of matchPaths
22 *
23 * @param {Array<{path: string, matchPath: string}>} value collection of matchPaths
24 */
25export const setMatchPaths = value => {
26 matchPaths = value
27}
28
29/**
30 * Return a matchpath url
31 * if `match-paths.json` contains `{ "/foo*": "/page1", ...}`, then
32 * `/foo?bar=far` => `/page1`
33 *
34 * @param {string} rawPathname A raw pathname
35 * @return {string|null}
36 */
37export const findMatchPath = rawPathname => {
38 const trimmedPathname = cleanPath(rawPathname)
39
40 for (const { matchPath, path } of matchPaths) {
41 if (match(matchPath, trimmedPathname)) {
42 return normalizePagePath(path)
43 }
44 }
45
46 return null
47}
48
49// Given a raw URL path, returns the cleaned version of it (trim off
50// `#` and query params), or if it matches an entry in
51// `match-paths.json`, its matched path is returned
52//
53// E.g. `/foo?bar=far` => `/foo`
54//
55// Or if `match-paths.json` contains `{ "/foo*": "/page1", ...}`, then
56// `/foo?bar=far` => `/page1`
57export const findPath = rawPathname => {
58 const trimmedPathname = trimPathname(rawPathname)
59
60 if (pathCache.has(trimmedPathname)) {
61 return pathCache.get(trimmedPathname)
62 }
63
64 let foundPath = findMatchPath(trimmedPathname)
65
66 if (!foundPath) {
67 foundPath = cleanPath(rawPathname)
68 }
69
70 pathCache.set(trimmedPathname, foundPath)
71
72 return foundPath
73}
74
75/**
76 * Clean a url and converts /index.html => /
77 * E.g. `/foo?bar=far` => `/foo`
78 *
79 * @param {string} rawPathname A raw pathname
80 * @return {string}
81 */
82export const cleanPath = rawPathname => {
83 const trimmedPathname = trimPathname(rawPathname)
84
85 let foundPath = trimmedPathname
86 if (foundPath === `/index.html`) {
87 foundPath = `/`
88 }
89
90 foundPath = normalizePagePath(foundPath)
91
92 return foundPath
93}