Skip to content

Commit dba6bf4

Browse files
committed
fix(util-endpoints): evaluateTemplate implementation without RegExp or Function argument
1 parent 8e10769 commit dba6bf4

File tree

2 files changed

+38
-30
lines changed

2 files changed

+38
-30
lines changed

packages/util-endpoints/src/utils/evaluateErrorRule.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ export const evaluateErrorRule = (errorRule: ErrorRuleObject, options: EvaluateO
1414
evaluateExpression(error, "Error", {
1515
...options,
1616
referenceRecord: { ...options.referenceRecord, ...referenceRecord },
17-
})
17+
}) as string
1818
);
1919
};
Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,46 @@
11
import { getAttr } from "../lib";
22
import { EvaluateOptions } from "../types";
33

4-
const ATTR_SHORTHAND_REGEX = new RegExp("\\${([\\w]+)#([\\w]+)}", "g");
5-
64
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> = [];
126

137
const templateContext = {
148
...options.endpointParams,
159
...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("");
3846
};

0 commit comments

Comments
 (0)