import { Chunk, ParamType } from './pathParser' import { last } from 'ramda' const evalCache = Object.create(null) const cachedEval = (fn: string): (path: string[]) => {} => { if (!evalCache[fn]) { /* see MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval * from the line "If you use the eval function indirectly..." **/ const globalEval = eval evalCache[fn] = globalEval(`(function magicCreateParams (path) {return {${fn}}})`) } return evalCache[fn] } function emptyFn () { return {} } export const createParamsConstructor = (pathChunks: Chunk[]) => { const pathKey = 'path' const keys = pathChunks .map(({ chunk, type }, index) => type === ParamType.param ? { chunk, index } : null) .filter(val => val !== null) .map(({ chunk, index }) => `${chunk}: ${pathKey}[${index}]`) .join(',') if (keys.length === 0) { return emptyFn } if (last(pathChunks).type === ParamType.wildcard) { const tail = pathChunks.length - 1 const restKey = last(pathChunks).chunk || '_' return cachedEval(`${keys}, ${restKey}: path.slice(0, ${tail}).join('/')`) } else { return cachedEval(`${keys}`) } }