UNPKG

@iopa/router

Version:

Lightweight and fast router for IOPA applications

63 lines (50 loc) 1.73 kB
/* eslint-disable @rushstack/security/no-unsafe-regexp */ import type { ParamMap, IRouterContext } from './node' import { Node } from './node' export type { ParamMap } from './node' export type ReplacementMap = number[] interface IInitOptions { reverse: boolean } export class Trie { public context: IRouterContext = { varIndex: 0 } public root: Node public constructor({ reverse }: IInitOptions = { reverse: false }) { this.root = new Node({ reverse }) } public insert(path: string, index: number): ParamMap { const paramMap: ParamMap = [] /** * - pattern (:label, :label{0-9]+}, ...) * - /* wildcard * - character */ const tokens = path.match(/(?::[^\/]+)|(?:\/\*$)|./g) // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore this.root.insert(tokens, index, paramMap, this.context) return paramMap } public buildRegExp(): [RegExp, ReplacementMap, ReplacementMap] { let regexp = this.root.buildRegExpStr() let captureIndex = 0 const indexReplacementMap: ReplacementMap = [] const paramReplacementMap: ReplacementMap = [] regexp = regexp.replace( /#(\d+)|@(\d+)|\.\*\$/g, // eslint-disable-next-line @typescript-eslint/naming-convention (_, handlerIndex, paramIndex) => { if (typeof handlerIndex !== 'undefined') { indexReplacementMap[++captureIndex] = Number(handlerIndex) return '$()' } if (typeof paramIndex !== 'undefined') { paramReplacementMap[Number(paramIndex)] = ++captureIndex return '' } return '' } ) return [new RegExp(`^${regexp}`), indexReplacementMap, paramReplacementMap] } }