path-to-regexp#Key TypeScript Examples

The following examples show how to use path-to-regexp#Key. 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: matchPath.ts    From next-core with GNU General Public License v3.0 6 votes vote down vote up
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 #2
Source File: index.ts    From erda-ui with GNU Affero General Public License v3.0 6 votes vote down vote up
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 #3
Source File: index.ts    From erda-ui with GNU Affero General Public License v3.0 6 votes vote down vote up
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 #4
Source File: findRoute.ts    From next-api-decorators with MIT License 6 votes vote down vote up
export function findRoute(
  cls: Record<string, any>,
  verb: string,
  path: string
): [Key[], RegExpExecArray | null | undefined, HandlerMethod | undefined] {
  const methods: Array<HandlerMethod> = Reflect.getMetadata(HTTP_METHOD_TOKEN, cls);

  const { pathToRegexp } = loadPackage('path-to-regexp');
  if (!pathToRegexp) {
    const method = methods.find(f => f.path === path && f.verb === verb);
    return [[], undefined, method ?? methods.find(f => f.path === '/' && f.verb === verb)];
  }

  const keys: Key[] = [];
  let match: RegExpExecArray | null | undefined;
  const method = methods.find(f => {
    match = pathToRegexp(f.path, keys).exec(path);

    const condition = f.verb === verb && match?.length;

    if (!condition) {
      keys.length = 0;
      match = undefined;
    }

    return condition;
  });

  return [keys, match, method];
}
Example #5
Source File: getParams.ts    From next-api-decorators with MIT License 6 votes vote down vote up
export function getParams(keys: Key[], match: RegExpExecArray | null | undefined): Record<string, any> {
  const params: Record<string, any> = {};

  if (keys?.length && match) {
    for (let i = 1; i < match.length; i++) {
      const key = keys[i - 1];
      const prop = key.name;
      const val = decodeParam(match[i]);

      if (val != null || !Object.hasOwnProperty.call(params, prop)) {
        params[prop] = val;
      }
    }
  }

  return params;
}
Example #6
Source File: translateUrl.ts    From next-translate-routes with MIT License 5 votes vote down vote up
export function translatePath(url: Url, locale?: string, { format }: Options = {}): Url {
  const { routesTree } = getNtrData()
  const returnFormat = format || typeof url
  const urlObject = typeof url === 'object' ? (url as UrlObject) : parseUrl(url, true)
  const { pathname, query, hash } = urlObject

  if (!pathname || !locale) {
    return returnFormat === 'object' ? url : formatUrl(url)
  }

  const pathParts = removeLangPrefix(pathname, true)

  const { translatedPathParts, augmentedQuery = {} } = translatePathParts({
    locale,
    pathParts,
    query: parseQuery(typeof query === 'string' ? query : stringifyQuery(query || {})),
    routeBranch: routesTree,
  })
  const path = translatedPathParts.join('/')
  const compiledPath = compilePath(path, { validate: false })(augmentedQuery)
  const paramNames = (parsePath(path).filter((token) => typeof token === 'object') as Key[]).map((token) => token.name)
  const remainingQuery = Object.keys(augmentedQuery).reduce(
    (acc, key) => ({
      ...acc,
      ...(paramNames.includes(key)
        ? {}
        : { [key]: (typeof query === 'object' && query?.[key]) || augmentedQuery[key] }),
    }),
    {},
  )

  const translatedPathname = `${routesTree.paths[locale] ? `/${routesTree.paths[locale]}` : ''}/${compiledPath}`

  const translatedUrlObject = {
    ...urlObject,
    hash,
    pathname: translatedPathname,
    query: remainingQuery,
  }

  return returnFormat === 'object' ? translatedUrlObject : formatUrl(translatedUrlObject)
}
Example #7
Source File: route.ts    From erda-ui with GNU Affero General Public License v3.0 4 votes vote down vote up
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;
    },
  },
})