diff --git a/.changeset/big-elephants-add.md b/.changeset/big-elephants-add.md
new file mode 100644
index 0000000000..86227b7171
--- /dev/null
+++ b/.changeset/big-elephants-add.md
@@ -0,0 +1,5 @@
+---
+"@clerk/shared": patch
+---
+
+Exports `match` utility from the `path-to-regexp` lib.
diff --git a/packages/shared/src/compiled/path-to-regexp/index.d.ts b/packages/shared/src/compiled/path-to-regexp/index.d.ts
new file mode 100644
index 0000000000..d05fd814da
--- /dev/null
+++ b/packages/shared/src/compiled/path-to-regexp/index.d.ts
@@ -0,0 +1,102 @@
+interface ParseOptions {
+ /**
+ * Set the default delimiter for repeat parameters. (default: `'/'`)
+ */
+ delimiter?: string;
+ /**
+ * List of characters to automatically consider prefixes when parsing.
+ */
+ prefixes?: string;
+}
+interface RegexpToFunctionOptions {
+ /**
+ * Function for decoding strings for params.
+ */
+ decode?: (value: string, token: Key) => string;
+}
+/**
+ * A match result contains data about the path match.
+ */
+interface MatchResult
{
+ path: string;
+ index: number;
+ params: P;
+}
+/**
+ * A match is either `false` (no match) or a match result.
+ */
+type Match
= false | MatchResult
;
+/**
+ * The match function takes a string and returns whether it matched the path.
+ */
+type MatchFunction
= (path: string) => Match
;
+/**
+ * Create path match function from `path-to-regexp` spec.
+ */
+declare function match
(
+ str: Path,
+ options?: ParseOptions & TokensToRegexpOptions & RegexpToFunctionOptions,
+): MatchFunction
;
+/**
+ * Metadata about a key.
+ */
+interface Key {
+ name: string | number;
+ prefix: string;
+ suffix: string;
+ pattern: string;
+ modifier: string;
+}
+interface TokensToRegexpOptions {
+ /**
+ * When `true` the regexp will be case sensitive. (default: `false`)
+ */
+ sensitive?: boolean;
+ /**
+ * When `true` the regexp won't allow an optional trailing delimiter to match. (default: `false`)
+ */
+ strict?: boolean;
+ /**
+ * When `true` the regexp will match to the end of the string. (default: `true`)
+ */
+ end?: boolean;
+ /**
+ * When `true` the regexp will match from the beginning of the string. (default: `true`)
+ */
+ start?: boolean;
+ /**
+ * Sets the final character for non-ending optimistic matches. (default: `/`)
+ */
+ delimiter?: string;
+ /**
+ * List of characters that can also be "end" characters.
+ */
+ endsWith?: string;
+ /**
+ * Encode path tokens for use in the `RegExp`.
+ */
+ encode?: (value: string) => string;
+}
+/**
+ * Supported `path-to-regexp` input types.
+ */
+type Path = string | RegExp | Array;
+/**
+ * Normalize the given path string, returning a regular expression.
+ *
+ * An empty array can be passed in for the keys, which will hold the
+ * placeholder key descriptions. For example, using `/user/:id`, `keys` will
+ * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
+ */
+declare function pathToRegexp(path: Path, keys?: Key[], options?: TokensToRegexpOptions & ParseOptions): RegExp;
+
+export {
+ type Match,
+ type MatchFunction,
+ type ParseOptions,
+ type Path,
+ type RegexpToFunctionOptions,
+ type TokensToRegexpOptions,
+ match,
+ pathToRegexp,
+};
diff --git a/packages/shared/src/compiled/path-to-regexp/index.js b/packages/shared/src/compiled/path-to-regexp/index.js
index d7e7902de1..7112d4ae2b 100644
--- a/packages/shared/src/compiled/path-to-regexp/index.js
+++ b/packages/shared/src/compiled/path-to-regexp/index.js
@@ -1,238 +1,331 @@
-/* eslint-disable no-redeclare */
+/* eslint-disable no-redeclare, curly */
function _(r) {
for (var n = [], e = 0; e < r.length; ) {
- var t = r[e];
- if (t === '*' || t === '+' || t === '?') {
- n.push({ type: 'MODIFIER', index: e, value: r[e++] });
+ var a = r[e];
+ if (a === '*' || a === '+' || a === '?') {
+ n.push({
+ type: 'MODIFIER',
+ index: e,
+ value: r[e++],
+ });
continue;
}
- if (t === '\\') {
- n.push({ type: 'ESCAPED_CHAR', index: e++, value: r[e++] });
+ if (a === '\\') {
+ n.push({
+ type: 'ESCAPED_CHAR',
+ index: e++,
+ value: r[e++],
+ });
continue;
}
- if (t === '{') {
- n.push({ type: 'OPEN', index: e, value: r[e++] });
+ if (a === '{') {
+ n.push({
+ type: 'OPEN',
+ index: e,
+ value: r[e++],
+ });
continue;
}
- if (t === '}') {
- n.push({ type: 'CLOSE', index: e, value: r[e++] });
+ if (a === '}') {
+ n.push({
+ type: 'CLOSE',
+ index: e,
+ value: r[e++],
+ });
continue;
}
- if (t === ':') {
- for (var u = '', a = e + 1; a < r.length; ) {
- var f = r.charCodeAt(a);
- if ((f >= 48 && f <= 57) || (f >= 65 && f <= 90) || (f >= 97 && f <= 122) || f === 95) {
- u += r[a++];
+ if (a === ':') {
+ for (var u = '', t = e + 1; t < r.length; ) {
+ var c = r.charCodeAt(t);
+ if ((c >= 48 && c <= 57) || (c >= 65 && c <= 90) || (c >= 97 && c <= 122) || c === 95) {
+ u += r[t++];
continue;
}
break;
}
- if (!u) {
- throw new TypeError('Missing parameter name at '.concat(e));
- }
- n.push({ type: 'NAME', index: e, value: u }), (e = a);
+ if (!u) throw new TypeError('Missing parameter name at '.concat(e));
+ n.push({
+ type: 'NAME',
+ index: e,
+ value: u,
+ }),
+ (e = t);
continue;
}
- if (t === '(') {
- var l = 1,
- d = '',
- a = e + 1;
- if (r[a] === '?') {
- throw new TypeError('Pattern cannot start with "?" at '.concat(a));
- }
- for (; a < r.length; ) {
- if (r[a] === '\\') {
- d += r[a++] + r[a++];
+ if (a === '(') {
+ var o = 1,
+ m = '',
+ t = e + 1;
+ if (r[t] === '?') throw new TypeError('Pattern cannot start with "?" at '.concat(t));
+ for (; t < r.length; ) {
+ if (r[t] === '\\') {
+ m += r[t++] + r[t++];
continue;
}
- if (r[a] === ')') {
- if ((l--, l === 0)) {
- a++;
+ if (r[t] === ')') {
+ if ((o--, o === 0)) {
+ t++;
break;
}
- } else if (r[a] === '(' && (l++, r[a + 1] !== '?')) {
- throw new TypeError('Capturing groups are not allowed at '.concat(a));
- }
- d += r[a++];
- }
- if (l) {
- throw new TypeError('Unbalanced pattern at '.concat(e));
+ } else if (r[t] === '(' && (o++, r[t + 1] !== '?'))
+ throw new TypeError('Capturing groups are not allowed at '.concat(t));
+ m += r[t++];
}
- if (!d) {
- throw new TypeError('Missing pattern at '.concat(e));
- }
- n.push({ type: 'PATTERN', index: e, value: d }), (e = a);
+ if (o) throw new TypeError('Unbalanced pattern at '.concat(e));
+ if (!m) throw new TypeError('Missing pattern at '.concat(e));
+ n.push({
+ type: 'PATTERN',
+ index: e,
+ value: m,
+ }),
+ (e = t);
continue;
}
- n.push({ type: 'CHAR', index: e, value: r[e++] });
+ n.push({
+ type: 'CHAR',
+ index: e,
+ value: r[e++],
+ });
}
- return n.push({ type: 'END', index: e, value: '' }), n;
+ return (
+ n.push({
+ type: 'END',
+ index: e,
+ value: '',
+ }),
+ n
+ );
}
-function D(r, n) {
+
+function F(r, n) {
n === void 0 && (n = {});
for (
var e = _(r),
- t = n.prefixes,
- u = t === void 0 ? './' : t,
- a = '[^'.concat(y(n.delimiter || '/#?'), ']+?'),
- f = [],
- l = 0,
- d = 0,
+ a = n.prefixes,
+ u = a === void 0 ? './' : a,
+ t = n.delimiter,
+ c = t === void 0 ? '/#?' : t,
+ o = [],
+ m = 0,
+ h = 0,
p = '',
- c = function (v) {
- if (d < e.length && e[d].type === v) {
- return e[d++].value;
- }
+ f = function (l) {
+ if (h < e.length && e[h].type === l) return e[h++].value;
},
- w = function (v) {
- var g = c(v);
- if (g !== void 0) {
- return g;
- }
- var h = e[d],
- b = h.type,
- N = h.index;
- throw new TypeError('Unexpected '.concat(b, ' at ').concat(N, ', expected ').concat(v));
+ w = function (l) {
+ var v = f(l);
+ if (v !== void 0) return v;
+ var E = e[h],
+ N = E.type,
+ S = E.index;
+ throw new TypeError('Unexpected '.concat(N, ' at ').concat(S, ', expected ').concat(l));
+ },
+ d = function () {
+ for (var l = '', v; (v = f('CHAR') || f('ESCAPED_CHAR')); ) l += v;
+ return l;
},
- A = function () {
- for (var v = '', g; (g = c('CHAR') || c('ESCAPED_CHAR')); ) {
- v += g;
+ M = function (l) {
+ for (var v = 0, E = c; v < E.length; v++) {
+ var N = E[v];
+ if (l.indexOf(N) > -1) return !0;
}
- return v;
+ return !1;
+ },
+ A = function (l) {
+ var v = o[o.length - 1],
+ E = l || (v && typeof v == 'string' ? v : '');
+ if (v && !E)
+ throw new TypeError('Must have text between two parameters, missing text after "'.concat(v.name, '"'));
+ return !E || M(E) ? '[^'.concat(s(c), ']+?') : '(?:(?!'.concat(s(E), ')[^').concat(s(c), '])+?');
};
- d < e.length;
+ h < e.length;
) {
- var s = c('CHAR'),
- C = c('NAME'),
- E = c('PATTERN');
- if (C || E) {
- var x = s || '';
- u.indexOf(x) === -1 && ((p += x), (x = '')),
- p && (f.push(p), (p = '')),
- f.push({ name: C || l++, prefix: x, suffix: '', pattern: E || a, modifier: c('MODIFIER') || '' });
+ var T = f('CHAR'),
+ x = f('NAME'),
+ C = f('PATTERN');
+ if (x || C) {
+ var g = T || '';
+ u.indexOf(g) === -1 && ((p += g), (g = '')),
+ p && (o.push(p), (p = '')),
+ o.push({
+ name: x || m++,
+ prefix: g,
+ suffix: '',
+ pattern: C || A(g),
+ modifier: f('MODIFIER') || '',
+ });
continue;
}
- var o = s || c('ESCAPED_CHAR');
- if (o) {
- p += o;
+ var i = T || f('ESCAPED_CHAR');
+ if (i) {
+ p += i;
continue;
}
- p && (f.push(p), (p = ''));
- var R = c('OPEN');
+ p && (o.push(p), (p = ''));
+ var R = f('OPEN');
if (R) {
- var x = A(),
- T = c('NAME') || '',
- i = c('PATTERN') || '',
- m = A();
+ var g = d(),
+ y = f('NAME') || '',
+ O = f('PATTERN') || '',
+ b = d();
w('CLOSE'),
- f.push({
- name: T || (i ? l++ : ''),
- pattern: T && !i ? a : i,
- prefix: x,
- suffix: m,
- modifier: c('MODIFIER') || '',
+ o.push({
+ name: y || (O ? m++ : ''),
+ pattern: y && !O ? A(g) : O,
+ prefix: g,
+ suffix: b,
+ modifier: f('MODIFIER') || '',
});
continue;
}
w('END');
}
- return f;
+ return o;
+}
+
+function H(r, n) {
+ var e = [],
+ a = P(r, e, n);
+ return I(a, e, n);
+}
+
+function I(r, n, e) {
+ e === void 0 && (e = {});
+ var a = e.decode,
+ u =
+ a === void 0
+ ? function (t) {
+ return t;
+ }
+ : a;
+ return function (t) {
+ var c = r.exec(t);
+ if (!c) return !1;
+ for (
+ var o = c[0],
+ m = c.index,
+ h = Object.create(null),
+ p = function (w) {
+ if (c[w] === void 0) return 'continue';
+ var d = n[w - 1];
+ d.modifier === '*' || d.modifier === '+'
+ ? (h[d.name] = c[w].split(d.prefix + d.suffix).map(function (M) {
+ return u(M, d);
+ }))
+ : (h[d.name] = u(c[w], d));
+ },
+ f = 1;
+ f < c.length;
+ f++
+ )
+ p(f);
+ return {
+ path: o,
+ index: m,
+ params: h,
+ };
+ };
}
-function y(r) {
+
+function s(r) {
return r.replace(/([.+*?=^!:${}()[\]|/\\])/g, '\\$1');
}
-function O(r) {
+
+function D(r) {
return r && r.sensitive ? '' : 'i';
}
-function M(r, n) {
- if (!n) {
- return r;
- }
- for (var e = /\((?:\?<(.*?)>)?(?!\?)/g, t = 0, u = e.exec(r.source); u; ) {
- n.push({ name: u[1] || t++, prefix: '', suffix: '', modifier: '', pattern: '' }), (u = e.exec(r.source));
- }
+
+function $(r, n) {
+ if (!n) return r;
+ for (var e = /\((?:\?<(.*?)>)?(?!\?)/g, a = 0, u = e.exec(r.source); u; )
+ n.push({
+ name: u[1] || a++,
+ prefix: '',
+ suffix: '',
+ modifier: '',
+ pattern: '',
+ }),
+ (u = e.exec(r.source));
return r;
}
-function S(r, n, e) {
- var t = r.map(function (u) {
+
+function W(r, n, e) {
+ var a = r.map(function (u) {
return P(u, n, e).source;
});
- return new RegExp('(?:'.concat(t.join('|'), ')'), O(e));
+ return new RegExp('(?:'.concat(a.join('|'), ')'), D(e));
}
-function F(r, n, e) {
- return H(D(r, e), n, e);
+
+function L(r, n, e) {
+ return U(F(r, e), n, e);
}
-function H(r, n, e) {
+
+function U(r, n, e) {
e === void 0 && (e = {});
for (
- var t = e.strict,
- u = t === void 0 ? !1 : t,
- a = e.start,
- f = a === void 0 ? !0 : a,
- l = e.end,
- d = l === void 0 ? !0 : l,
- p = e.encode,
- c =
- p === void 0
- ? function (N) {
- return N;
+ var a = e.strict,
+ u = a === void 0 ? !1 : a,
+ t = e.start,
+ c = t === void 0 ? !0 : t,
+ o = e.end,
+ m = o === void 0 ? !0 : o,
+ h = e.encode,
+ p =
+ h === void 0
+ ? function (v) {
+ return v;
}
- : p,
- w = e.delimiter,
- A = w === void 0 ? '/#?' : w,
- s = e.endsWith,
- C = s === void 0 ? '' : s,
- E = '['.concat(y(C), ']|$'),
- x = '['.concat(y(A), ']'),
- o = f ? '^' : '',
- R = 0,
- T = r;
- R < T.length;
- R++
+ : h,
+ f = e.delimiter,
+ w = f === void 0 ? '/#?' : f,
+ d = e.endsWith,
+ M = d === void 0 ? '' : d,
+ A = '['.concat(s(M), ']|$'),
+ T = '['.concat(s(w), ']'),
+ x = c ? '^' : '',
+ C = 0,
+ g = r;
+ C < g.length;
+ C++
) {
- var i = T[R];
- if (typeof i == 'string') {
- o += y(c(i));
- } else {
- var m = y(c(i.prefix)),
- v = y(c(i.suffix));
- if (i.pattern) {
- if ((n && n.push(i), m || v)) {
+ var i = g[C];
+ if (typeof i == 'string') x += s(p(i));
+ else {
+ var R = s(p(i.prefix)),
+ y = s(p(i.suffix));
+ if (i.pattern)
+ if ((n && n.push(i), R || y))
if (i.modifier === '+' || i.modifier === '*') {
- var g = i.modifier === '*' ? '?' : '';
- o += '(?:'
- .concat(m, '((?:')
+ var O = i.modifier === '*' ? '?' : '';
+ x += '(?:'
+ .concat(R, '((?:')
.concat(i.pattern, ')(?:')
- .concat(v)
- .concat(m, '(?:')
+ .concat(y)
+ .concat(R, '(?:')
.concat(i.pattern, '))*)')
- .concat(v, ')')
- .concat(g);
- } else {
- o += '(?:'.concat(m, '(').concat(i.pattern, ')').concat(v, ')').concat(i.modifier);
- }
- } else {
- i.modifier === '+' || i.modifier === '*'
- ? (o += '((?:'.concat(i.pattern, ')').concat(i.modifier, ')'))
- : (o += '('.concat(i.pattern, ')').concat(i.modifier));
+ .concat(y, ')')
+ .concat(O);
+ } else x += '(?:'.concat(R, '(').concat(i.pattern, ')').concat(y, ')').concat(i.modifier);
+ else {
+ if (i.modifier === '+' || i.modifier === '*')
+ throw new TypeError('Can not repeat "'.concat(i.name, '" without a prefix and suffix'));
+ x += '('.concat(i.pattern, ')').concat(i.modifier);
}
- } else {
- o += '(?:'.concat(m).concat(v, ')').concat(i.modifier);
- }
+ else x += '(?:'.concat(R).concat(y, ')').concat(i.modifier);
}
}
- if (d) {
- u || (o += ''.concat(x, '?')), (o += e.endsWith ? '(?='.concat(E, ')') : '$');
- } else {
- var h = r[r.length - 1],
- b = typeof h == 'string' ? x.indexOf(h[h.length - 1]) > -1 : h === void 0;
- u || (o += '(?:'.concat(x, '(?=').concat(E, '))?')), b || (o += '(?='.concat(x, '|').concat(E, ')'));
+ if (m) u || (x += ''.concat(T, '?')), (x += e.endsWith ? '(?='.concat(A, ')') : '$');
+ else {
+ var b = r[r.length - 1],
+ l = typeof b == 'string' ? T.indexOf(b[b.length - 1]) > -1 : b === void 0;
+ u || (x += '(?:'.concat(T, '(?=').concat(A, '))?')), l || (x += '(?='.concat(T, '|').concat(A, ')'));
}
- return new RegExp(o, O(e));
+ return new RegExp(x, D(e));
}
+
function P(r, n, e) {
- return r instanceof RegExp ? M(r, n) : Array.isArray(r) ? S(r, n, e) : F(r, n, e);
+ return r instanceof RegExp ? $(r, n) : Array.isArray(r) ? W(r, n, e) : L(r, n, e);
}
-export { P as pathToRegexp };
+export { H as match, P as pathToRegexp };
diff --git a/packages/shared/src/pathToRegexp.ts b/packages/shared/src/pathToRegexp.ts
index 6400429565..fcb11a1e4f 100644
--- a/packages/shared/src/pathToRegexp.ts
+++ b/packages/shared/src/pathToRegexp.ts
@@ -1,12 +1,36 @@
-import { pathToRegexp as pathToRegexpBase } from './compiled/path-to-regexp';
+import type {
+ Match,
+ MatchFunction,
+ ParseOptions,
+ Path,
+ RegexpToFunctionOptions,
+ TokensToRegexpOptions,
+} from './compiled/path-to-regexp';
+import { match as matchBase, pathToRegexp as pathToRegexpBase } from './compiled/path-to-regexp';
export const pathToRegexp = (path: string) => {
try {
// @ts-ignore no types exists for the pre-compiled package
- return pathToRegexpBase(path) as RegExp;
+ return pathToRegexpBase(path);
} catch (e: any) {
throw new Error(
- `Invalid path: ${path}.\nConsult the documentation of path-to-regexp here: https://github.com/pillarjs/path-to-regexp\n${e.message}`,
+ `Invalid path: ${path}.\nConsult the documentation of path-to-regexp here: https://github.com/pillarjs/path-to-regexp/tree/6.x\n${e.message}`,
);
}
};
+
+export function match(
+ str: Path,
+ options?: ParseOptions & TokensToRegexpOptions & RegexpToFunctionOptions,
+): MatchFunction
{
+ try {
+ // @ts-ignore no types exists for the pre-compiled package
+ return matchBase(str, options);
+ } catch (e: any) {
+ throw new Error(
+ `Invalid path and options: Consult the documentation of path-to-regexp here: https://github.com/pillarjs/path-to-regexp/tree/6.x\n${e.message}`,
+ );
+ }
+}
+
+export { type Match, type MatchFunction };