pages-dev-util.ts 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. /**
  2. * @param pathname A pathname string, such as `/foo` or `/foo/bar`
  3. * @param routingRule The routing rule, such as `/foo/*`
  4. * @returns True if pathname matches the routing rule
  5. *
  6. * / -> /
  7. * /* -> /*
  8. * /foo -> /foo
  9. * /foo* -> /foo, /foo-bar, /foo/*
  10. * /foo/* -> /foo, /foo/bar
  11. */
  12. export function isRoutingRuleMatch(
  13. pathname: string,
  14. routingRule: string
  15. ): boolean {
  16. // sanity checks
  17. if (!pathname) {
  18. throw new Error("Pathname is undefined.");
  19. }
  20. if (!routingRule) {
  21. throw new Error("Routing rule is undefined.");
  22. }
  23. const ruleRegExp = transformRoutingRuleToRegExp(routingRule);
  24. return pathname.match(ruleRegExp) !== null;
  25. }
  26. function transformRoutingRuleToRegExp(rule: string): RegExp {
  27. let transformedRule;
  28. if (rule === "/" || rule === "/*") {
  29. transformedRule = rule;
  30. } else if (rule.endsWith("/*")) {
  31. // make `/*` an optional group so we can match both /foo/* and /foo
  32. // /foo/* => /foo(/*)?
  33. transformedRule = `${rule.substring(0, rule.length - 2)}(/*)?`;
  34. } else if (rule.endsWith("/")) {
  35. // make `/` an optional group so we can match both /foo/ and /foo
  36. // /foo/ => /foo(/)?
  37. transformedRule = `${rule.substring(0, rule.length - 1)}(/)?`;
  38. } else if (rule.endsWith("*")) {
  39. transformedRule = rule;
  40. } else {
  41. transformedRule = `${rule}(/)?`;
  42. }
  43. // /foo* => /foo.* => ^/foo.*$
  44. // /*.* => /*\.* => /.*\..* => ^/.*\..*$
  45. transformedRule = `^${transformedRule
  46. .replaceAll(/\./g, "\\.")
  47. .replaceAll(/\*/g, ".*")}$`;
  48. // ^/foo.*$ => /^\/foo.*$/
  49. return new RegExp(transformedRule);
  50. }