이 라이브러리는 안전하고 유연한 템플릿 문자열 파싱 및 평가 기능을 제공합니다. 복잡한 수학 표현식, 변수 참조, 함수 호출, 배열 인덱싱 등을 지원하며, eval()
또는 new Function()
을 사용하지 않아 보안상 안전합니다.
npm install safe-template-parser
최신 릴리스에서 safe-template-parser.min.js
파일을 다운로드하여 프로젝트에 포함할 수 있습니다.
- 변수 참조 및 중첩 객체 속성 접근
- 배열 인덱싱 및 배열 요소의 속성 접근
- 기본 산술 연산 (+, -, *, /, %, ^)
- 비교 연산 (==, !=, <, <=, >, >=, ===, !==)
- 논리 연산 (&&, ||, !)
- 삼항 연산자 (? :)
- 배열 리터럴 및 객체 리터럴
- 내장 함수 호출 (min, max, abs, round, floor, ceil)
- 사용자 정의 함수 호출 지원 (화이트리스트 방식)
- 괄호를 사용한 복잡한 표현식
- 안전한 평가 (no eval, no new Function)
// ESM
import { parseTemplateString } from 'safe-template-parser';
// CommonJS
const { parseTemplateString } = require('safe-template-parser');
템플릿 문자열 내에서 {{ }}
를 사용하여 표현식을 작성합니다.
const template = "안녕하세요, {{name}}님. 당신의 나이는 {{age}}세이고, {{address.city}}에 살고 계시네요. " +
"5년 후의 나이는 {{age + 5}}세입니다. " +
"나이의 제곱근은 {{round(abs(age) ^ 0.5)}}입니다. " +
"첫 번째 친구의 이름은 {{friends[0].name}}이고, " +
"가장 나이 많은 친구는 {{max(friends[0].age, friends[1].age)}}세입니다. " +
"사용자 정의 함수 결과: {{customFunc(age)}}세입니다. " +
"복잡한 계산: {{complexCalc(age, 10)}}입니다.";
템플릿에서 사용할 변수들을 포함하는 데이터 객체와, 템플릿에서 호출을 허용할 함수들을 포함하는 allowedFunctions
객체를 준비합니다.
const data = {
name: "홍길동",
age: 30,
address: {
city: "서울"
},
friends: [
{ name: "김철수", age: 28 },
{ name: "이영희", age: 32 }
]
};
// 템플릿에서 호출을 허용할 사용자 정의 함수들을 정의합니다.
// 이 객체에 명시적으로 정의된 함수만 템플릿 내에서 호출될 수 있습니다.
const allowedFunctions = {
customFunc: (age) => age * 1.5,
complexCalc: (a, b) => (a + b) * 2,
// 여기에 안전하다고 판단되는 다른 함수들을 추가합니다.
};
parseTemplateString
함수를 사용하여 템플릿을 파싱하고 결과를 출력합니다. allowedFunctions
객체를 세 번째 인자로 전달합니다.
const result = parseTemplateString(template, data, allowedFunctions);
console.log(result);
- 덧셈:
+
- 뺄셈:
-
- 곱셈:
*
- 나눗셈:
/
- 모듈로(나머지):
%
- 거듭제곱:
^
- 비교:
==
,!=
,<
,<=
,>
,>=
,===
,!==
- 논리:
&&
,||
,!
- 삼항 연산자:
? :
min(a, b, ...)
: 최솟값 반환max(a, b, ...)
: 최댓값 반환abs(x)
: 절댓값 반환round(x)
: 반올림floor(x)
: 내림ceil(x)
: 올림
parseTemplateString
함수에 세 번째 인자로 allowedFunctions
객체를 전달하여 템플릿 내에서 호출할 수 있는 사용자 정의 함수를 명시적으로 허용합니다. data
객체에 포함된 함수는 더 이상 템플릿에서 직접 호출되지 않습니다. 이는 임의 코드 실행을 방지하여 보안을 강화합니다.
// 템플릿에서 호출을 허용할 함수 목록
const mySafeFunctions = {
greet: (name) => `Hello, ${name}`,
calculate: (x, y) => x * y,
};
const data = { userName: "Alice" };
const template = "{{ greet(userName) }}. Result: {{ calculate(5, 10) }}";
// parseTemplateString 호출 시 allowedFunctions를 전달
const result = parseTemplateString(template, data, mySafeFunctions);
console.log(result); // 출력: "Hello, Alice. Result: 50"
- 배열 인덱싱:
array[index]
(범위를 벗어나면undefined
반환) - 객체 속성 접근:
object.property
(존재하지 않으면undefined
반환) - 배열 요소의 속성 접근:
array[index].property
- 템플릿 내의 표현식은
{{ }}
안에 작성해야 합니다. - 존재하지 않는 변수를 참조하면 오류가 발생합니다.
allowedFunctions
에 명시적으로 등록되지 않은 함수는 템플릿 내에서 호출할 수 없습니다.data
객체에 함수를 포함하더라도 실행되지 않습니다.- 잘못된 형식의 숫자 리터럴 (예:
1.2.3
)은 파싱 오류를 발생시킵니다.
파싱 또는 평가 중 오류가 발생하면, 콘솔에 오류 메시지가 출력되고 원래의 표현식이 그대로 반환됩니다.
const template = "잘못된 표현식: {{ nonexistent_function() }}";
const result = parseTemplateString(template, {});
// 결과: "잘못된 표현식: {{ nonexistent_function() }}"
// 콘솔에 오류 메시지 출력