path-to-regexp#pathToRegexp TypeScript Examples
The following examples show how to use
path-to-regexp#pathToRegexp.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.ts From uni-cloud-router with Apache License 2.0 | 7 votes |
function routeMatch(pattern: Condition) {
if (typeof pattern === 'string') {
const reg = pathToRegexp(pattern, [], { end: false })
if (reg.global) reg.lastIndex = 0
return (ctx: any) => reg.test(ctx.event.action)
}
if (pattern instanceof RegExp) {
return (ctx: any) => {
if (pattern.global) pattern.lastIndex = 0
return pattern.test(ctx.event.action)
}
}
if (typeof pattern === 'function') return pattern
if (Array.isArray(pattern)) {
const matchs = pattern.map((item) => routeMatch(item)) as any
return (ctx: any) => matchs.some((match: Function) => match(ctx))
}
throw new Error(
'match/ignore pattern must be RegExp, Array or String, but got ' + pattern
)
}
Example #2
Source File: operation.ts From openapi-mock-express-middleware with MIT License | 6 votes |
constructor({
method,
path,
operation,
securitySchemes,
generator,
parentParams,
}: {
path: string;
method: string;
operation: OpenAPIV3.OperationObject;
generator: JSF;
securitySchemes?: { [key: string]: OpenAPIV3.SecuritySchemeObject };
parentParams?: (OpenAPIV3.ReferenceObject | OpenAPIV3.ParameterObject)[];
}) {
this.pathPattern = path.replace(/\{([^/}]+)\}/g, (p1: string, p2: string): string => `:${p2}`);
this.parentParams = parentParams || null;
this.method = method.toUpperCase();
this.operation = operation;
this.securitySchemes = securitySchemes || null;
this.generator = generator;
this.pathRegexp = pathToRegexp(this.pathPattern);
}
Example #3
Source File: matchPath.ts From next-core with GNU General Public License v3.0 | 6 votes |
function compilePath(path: string, options: CompileOptions): CompileResult {
const cacheKey = `${options.end}${options.strict}${options.sensitive}`;
if (!cache.has(cacheKey)) {
cache.set(cacheKey, new Map());
}
const pathCache = cache.get(cacheKey);
if (pathCache.has(path)) {
return pathCache.get(path);
}
const keys: Key[] = [];
const regexp = pathToRegexp(path, keys, options);
const result = { regexp, keys };
if (cacheCount < cacheLimit) {
pathCache.set(path, result);
cacheCount++;
}
return result;
}
Example #4
Source File: index.ts From erda-ui with GNU Affero General Public License v3.0 | 6 votes |
extractPathParams = (path: string, params?: Obj<any>) => {
const keys: Key[] = [];
pathToRegexp(path, keys);
const pathParams = {} as Obj<string>;
const bodyOrQuery = { ...params };
if (keys.length > 0) {
keys.forEach(({ name }) => {
pathParams[name] = bodyOrQuery[name];
delete bodyOrQuery[name];
});
}
return {
pathParams,
bodyOrQuery,
};
}
Example #5
Source File: index.ts From erda-ui with GNU Affero General Public License v3.0 | 6 votes |
extractPathParams = (path: string, params?: Obj) => {
const keys: Key[] = [];
pathToRegexp(path, keys);
const pathParams = {};
const bodyOrQuery = { ...params };
if (keys.length > 0) {
keys.forEach(({ name }) => {
pathParams[name] = bodyOrQuery[name];
delete bodyOrQuery[name];
});
}
return {
pathParams,
bodyOrQuery,
};
}
Example #6
Source File: page.ts From native with MIT License | 6 votes |
ignoreURLs = (urlString: string, ignoreList: boolean | TypeIgnoreURLsList) => {
if (typeof ignoreList == "boolean")
return ignoreList;
let _keys = [];
return !(ignoreList as TypeIgnoreURLsList)
.every(val => pathToRegexp(val, _keys, {
start: false,
end: false
}).exec(urlString) == null);
}
Example #7
Source File: router.ts From native with MIT License | 6 votes |
/** Convert strings into path match functions */
public parsePath(path: TypeRouteStyle): RegExp | boolean {
if (typeof path === "string" || path instanceof RegExp || Array.isArray(path)) {
let _keys = [];
return pathToRegexp(path as Path, _keys, {
start: false,
end: false
});
} else if (typeof path === "boolean")
return path ? /.*/ : path;
throw "[Router] only regular expressions, strings, booleans and arrays of regular expressions and strings are accepted as paths.";
}
Example #8
Source File: Server.ts From double-agent with MIT License | 6 votes |
constructor(collect: Collect, httpServerPort: number) {
this.collect = collect;
this.httpServerPort = httpServerPort;
this.httpServer = new http.Server(this.handleRequest.bind(this));
Object.keys(this.endpointsByRoute).forEach(route => {
const keys = [];
const regexp = pathToRegexp(route, keys);
this.routeMetaByRegexp.set(regexp, { route, keys });
});
}
Example #9
Source File: route.ts From erda-ui with GNU Affero General Public License v3.0 | 4 votes |
routeInfoStore = createStore({
name: 'routeInfo',
state: initRouteInfo,
reducers: {
$_updateRouteInfo(
state,
location: { pathname: string; search: string; key: string },
extraData?: any,
extraPayload?: { force?: boolean },
) {
const { pathname, search, key: urlKey } = location;
const { force = false } = extraPayload || {};
const prevRouteInfo = state;
if (!force && prevPath === pathname && search === prevSearch) {
return prevRouteInfo;
}
prevPath = pathname;
prevSearch = search;
const query = { ...parse(search, { arrayFormat: 'bracket' }) }; // parse出来的对象prototype为null,fast-deep-equal判断时报错
let routes: IRouteInfo[] = [];
const params: Obj = {};
const { routePatterns, routeMap, parsed } = extraData || prevRouteInfo;
let currentRoute = null;
let routeMarks: string[] = [];
const findParent = (item: any) => {
const { _parent, mark } = item;
if (mark) {
routeMarks.push(mark);
}
if (_parent) {
routes.push(_parent);
findParent(_parent);
}
};
for (let i = 0; i < routePatterns?.length; i++) {
const pattern = routePatterns[i];
const keys: Key[] = [];
const match = pathToRegexp(pattern, keys).exec(pathname);
if (match) {
keys.forEach((k, j) => {
if (k.name !== 0) {
// 移除 * 号匹配时的0字段
params[k.name] = match[j + 1];
}
});
currentRoute = routeMap[pattern].route;
const routeLevel = pattern.split('/').length;
Object.keys(queryLevelMap).forEach((level) => {
// 清除大于当前层级(更深)的路由的query
if (routeLevel < level) {
Object.values(queryLevelMap[level]).forEach((r) => {
r.routeQuery = {};
});
}
});
// 如果需要保持路由query
if (currentRoute.keepQuery) {
currentRoute.routeQuery = { ...currentRoute.routeQuery, ...query };
queryLevelMap[routeLevel] = queryLevelMap[routeLevel] || {};
queryLevelMap[routeLevel][pattern] = currentRoute;
}
routes = [currentRoute];
routeMarks = [];
findParent(currentRoute);
break;
}
}
const curUrlPaths = [...state.urlPathRecord];
const curUrlFull = new Set(state.urlFullRecord);
let urlState = 'new';
if (curUrlFull.has(urlKey) && curUrlPaths.length > 1) {
if (curUrlPaths.includes(urlKey)) {
urlState = 'back';
curUrlPaths.pop();
} else {
urlState = 'forward';
curUrlPaths.push(urlKey);
}
} else if (!(curUrlPaths.length === 1 && curUrlPaths.includes(urlKey))) {
// forbidden first time execute $_updateRouteInfo more than once;
curUrlPaths.push(urlKey);
}
curUrlFull.add(urlKey);
const markedRoutePreview = {
...state.markedRoutePreview,
...(currentRoute?.searchMark ? { [currentRoute.searchMark]: search } : {}),
};
const routeInfo = {
prevRouteInfo,
params,
query,
routes,
currentRoute,
markedRoutePreview,
urlFullRecord: curUrlFull,
urlPathRecord: curUrlPaths,
urlState,
routePatterns,
routeMap,
parsed,
routeMarks,
isIn: (level: string) => routeMarks.includes(level),
isMatch: (pattern: string) => !!pathToRegexp(pattern, []).exec(pathname),
isEntering: (level: string) => routeMarks.includes(level) && !prevRouteInfo.routeMarks.includes(level),
isLeaving: (level: string) => !routeMarks.includes(level) && prevRouteInfo.routeMarks.includes(level),
};
return routeInfo;
},
},
})
Example #10
Source File: config.tsx From next-translate-routes with MIT License | 4 votes |
getPageReRoutes = <L extends string>({
locales,
routeSegments,
defaultLocale,
}: {
locales: L[]
routeSegments: TRouteSegment<L>[]
defaultLocale?: L
}): TReRoutes => {
/** If there is only one path possible: it is common to all locales and to files. No redirection nor rewrite is needed. */
if (!routeSegments.some(({ paths }) => Object.keys(paths).length > 1)) {
return { rewrites: [], redirects: [] }
}
/** Get a translated path or base path */
const getPath = (locale: L | 'default') =>
`/${routeSegments
.map(({ paths }) => paths[locale] || paths.default)
.filter((pathPart) => pathPart && !ignoreSegmentPathRegex.test(pathPart))
.join('/')}`
/** File path in path-to-regexp syntax (cannot be customised in routes data files) */
const basePath = `/${routeSegments
.map(({ name, paths: { default: defaultPath } }) => {
const match = defaultPath.match(ignoreSegmentPathRegex) || []
// If a pattern is added to the ignore token "."
return fileNameToPath(name) + (match[1] || '')
})
.filter((pathPart) => pathPart)
.join('/')}`
/**
* ```
* [
* { locales: ['en'], path: '/english/path/without/locale/prefix' },
* { locales: ['fr'], path: '/french/path/without/locale/prefix' },
* { locales: ['es', 'pt'], path: '/path/common/to/several/locales' },
* ]
* ```
* Each locale cannot appear more than once. Item is ignored if its path would be the same as basePath.
*/
const sourceList = locales.reduce((acc, locale) => {
const source = getPath(locale)
if (source === basePath) {
return acc
}
const { sourceLocales = [] } = acc.find((sourceItem) => sourceItem.source === source) || {}
return [
...acc.filter((sourceItem) => sourceItem.source !== source),
{ source, sourceLocales: [...sourceLocales, locale] },
]
}, [] as { sourceLocales: L[]; source: string }[])
const redirects = locales.reduce((acc, locale) => {
const localePath = getPath(locale)
const destination = `${locale === defaultLocale ? '' : `/${locale}`}${sourceToDestination(localePath)}`
return [
...acc,
...sourceList
.filter(({ sourceLocales }) => !sourceLocales.includes(locale))
// Redirect from base path so that it does not display the page but only the translated path does
.concat(...(localePath === basePath ? [] : [{ sourceLocales: [], source: basePath }]))
.reduce((acc, { source: rawSource }) => {
const source = `/${locale}${rawSource}`
const sourceSegments = source.split('/')
// Look for similar redirects
const similarIndex = getSimilarIndex(sourceSegments, acc)
// If similar redirect exist, merge the new one
if (similarIndex >= 0) {
const similar = acc[similarIndex]
const mergedWithSimilar = {
...similar,
source: similar.source
.split('/')
.map((similarSegment, index) =>
sourceSegments[index] === similarSegment
? similarSegment
: mergeOrRegex(similarSegment, sourceSegments[index]),
)
.join('/'),
}
// Avoid to merge path that would introduce redirect loop
if (!pathToRegexp(mergedWithSimilar.source).test(destination)) {
return [...acc.slice(0, similarIndex), mergedWithSimilar, ...acc.slice(similarIndex + 1)]
}
}
// Else append the new redirect
return [
...acc,
{
source,
destination,
locale: false as const,
permanent: true,
},
]
}, [] as Redirect[])
.filter(({ source, destination }) => sourceToDestination(source) !== destination),
]
}, [] as Redirect[])
const destination = sourceToDestination(basePath)
const rewrites: Rewrite[] = sourceList.reduce((acc, { source }) => {
if (sourceToDestination(source) === destination) {
return acc
}
const sourceSegments = source.split('/')
// Look for similar rewrites
const similarIndex = getSimilarIndex(sourceSegments, acc)
// If similar rewrite exist, merge the new one
if (similarIndex >= 0) {
const similar = acc[similarIndex]
return [
...acc.slice(0, similarIndex),
{
...similar,
source: similar.source
.split('/')
.map((similarSegment, index) =>
similarSegment === sourceSegments[index]
? similarSegment
: `(${similarSegment.replace(/\(|\)/g, '').split('|').concat(sourceSegments[index]).join('|')})`,
)
.join('/'),
},
...acc.slice(similarIndex + 1),
]
}
// Else append a new rewrite
return [
...acc,
{
source,
destination,
},
]
}, [] as Rewrite[])
return { redirects, rewrites }
}