|
1 | 1 | import { getAttr } from "../lib";
|
2 | 2 | import { EvaluateOptions } from "../types";
|
3 | 3 |
|
4 |
| -const ATTR_SHORTHAND_REGEX = new RegExp("\\${([\\w]+)#([\\w]+)}", "g"); |
5 |
| - |
6 | 4 | export const evaluateTemplate = (template: string, options: EvaluateOptions) => {
|
7 |
| - const templateToEvaluate = template |
8 |
| - // Replace `{value}` with `${value}` |
9 |
| - .replace(new RegExp(`\{([^{}]+)\}`, "g"), "${$1}") |
10 |
| - // Replace `{${value}}` with `{value}` |
11 |
| - .replace(new RegExp(`\{\\$\{([^{}]+)\}\}`, "g"), "{$1}"); |
| 5 | + const evaluatedTemplateArr: Array<String> = []; |
12 | 6 |
|
13 | 7 | const templateContext = {
|
14 | 8 | ...options.endpointParams,
|
15 | 9 | ...options.referenceRecord,
|
16 |
| - }; |
17 |
| - |
18 |
| - const attrShortHandList = templateToEvaluate.match(ATTR_SHORTHAND_REGEX) || []; |
19 |
| - |
20 |
| - const attrShortHandMap = attrShortHandList.reduce((acc, attrShortHand) => { |
21 |
| - const indexOfHash = attrShortHand.indexOf("#"); |
22 |
| - const refName = attrShortHand.substring(2, indexOfHash); |
23 |
| - const attrName = attrShortHand.substring(indexOfHash + 1, attrShortHand.length - 1); |
24 |
| - acc[attrShortHand] = getAttr(templateContext[refName] as Record<string, any>, attrName) as string; |
25 |
| - return acc; |
26 |
| - }, {} as Record<string, string>); |
27 |
| - |
28 |
| - const templateWithAttr = Object.entries(attrShortHandMap).reduce( |
29 |
| - (acc, [shortHand, value]) => acc.replace(shortHand, value), |
30 |
| - templateToEvaluate |
31 |
| - ); |
32 |
| - |
33 |
| - const templateContextNames = Object.keys(templateContext); |
34 |
| - const templateContextValues = Object.values(templateContext); |
35 |
| - const templateWithTildeEscaped = templateWithAttr.replace(/\`/g, "\\`"); |
36 |
| - |
37 |
| - return new Function(...templateContextNames, `return \`${templateWithTildeEscaped}\``)(...templateContextValues); |
| 10 | + } as Record<string, string>; |
| 11 | + |
| 12 | + for (let i = 0; i < template.length; i++) { |
| 13 | + const char = template[i]; |
| 14 | + const nextChar = template[i + 1]; |
| 15 | + |
| 16 | + if (char === "{") { |
| 17 | + if (nextChar === "{") { |
| 18 | + // Escaped expression, skip next char |
| 19 | + i++; |
| 20 | + evaluatedTemplateArr.push(char); |
| 21 | + } else { |
| 22 | + const closingBraceIndex = template.indexOf("}", i); |
| 23 | + const parameterName = template.substring(i + 1, closingBraceIndex); |
| 24 | + |
| 25 | + if (parameterName.includes("#")) { |
| 26 | + const [refName, attrName] = parameterName.split("#"); |
| 27 | + evaluatedTemplateArr.push(getAttr(templateContext[refName], attrName) as string); |
| 28 | + } else { |
| 29 | + evaluatedTemplateArr.push(templateContext[parameterName]); |
| 30 | + } |
| 31 | + |
| 32 | + i = closingBraceIndex; |
| 33 | + } |
| 34 | + } else if (char === "}") { |
| 35 | + if (nextChar === "}") { |
| 36 | + // Escaped expression, skip next char |
| 37 | + i++; |
| 38 | + } |
| 39 | + evaluatedTemplateArr.push(char); |
| 40 | + } else { |
| 41 | + evaluatedTemplateArr.push(char); |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + return evaluatedTemplateArr.join(""); |
38 | 46 | };
|
0 commit comments