Skip to content

ES6 리터럴 템플릿 문자열 생성을 일반 문자열로 유사 동작하도록 하는 안전한 PureJS 함수 (Function acting to correspond to ES6 template string)

License

Notifications You must be signed in to change notification settings

getCurrentThread/SafeTemplateStringJS

Repository files navigation

Safe Template String Parser

이 라이브러리는 안전하고 유연한 템플릿 문자열 파싱 및 평가 기능을 제공합니다. 복잡한 수학 표현식, 변수 참조, 함수 호출, 배열 인덱싱 등을 지원하며, eval() 또는 new Function()을 사용하지 않아 보안상 안전합니다.

설치

npm을 통한 설치

npm install safe-template-parser

직접 다운로드

최신 릴리스에서 safe-template-parser.min.js 파일을 다운로드하여 프로젝트에 포함할 수 있습니다.

주요 기능

  • 변수 참조 및 중첩 객체 속성 접근
  • 배열 인덱싱 및 배열 요소의 속성 접근
  • 기본 산술 연산 (+, -, *, /, %, ^)
  • 비교 연산 (==, !=, <, <=, >, >=, ===, !==)
  • 논리 연산 (&&, ||, !)
  • 삼항 연산자 (? :)
  • 배열 리터럴 및 객체 리터럴
  • 내장 함수 호출 (min, max, abs, round, floor, ceil)
  • 사용자 정의 함수 호출 지원 (화이트리스트 방식)
  • 괄호를 사용한 복잡한 표현식
  • 안전한 평가 (no eval, no new Function)

사용 방법

1. 라이브러리 가져오기

// ESM
import { parseTemplateString } from 'safe-template-parser';

// CommonJS
const { parseTemplateString } = require('safe-template-parser');

2. 템플릿 문자열 정의

템플릿 문자열 내에서 {{ }} 를 사용하여 표현식을 작성합니다.

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)}}입니다.";

3. 데이터 객체 및 허용된 함수 준비

템플릿에서 사용할 변수들을 포함하는 데이터 객체와, 템플릿에서 호출을 허용할 함수들을 포함하는 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,
  // 여기에 안전하다고 판단되는 다른 함수들을 추가합니다.
};

4. 템플릿 파싱 및 결과 출력

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() }}"
// 콘솔에 오류 메시지 출력

About

ES6 리터럴 템플릿 문자열 생성을 일반 문자열로 유사 동작하도록 하는 안전한 PureJS 함수 (Function acting to correspond to ES6 template string)

Resources

License

Stars

Watchers

Forks

Packages

No packages published