@@ -8,6 +8,14 @@ const TEMPLATE_REGEX = /\{\{\s*([\w\.\[\]]+)(?:\((.*)\))?(?:\s*\|\s([a-zA-Z*]\w*
8
8
const JSON_PATH_REGEX = / ^ [ a - z A - Z _ ] \w * ( (?: \. \w + ) | (?: \[ \d + \] ) ) * $ /
9
9
const JSON_PATH_TOKEN = / ( ^ [ a - z A - Z _ ] \w * ) | ( \. [ a - z A - Z _ ] \w * ) | ( \[ \d + \] ) / g
10
10
11
+ function mergeMaps ( map1 , map2 ) {
12
+ return new Map ( [ ...map1 , ...map2 ] ) ;
13
+ }
14
+
15
+ function htmlEscape ( input ) {
16
+ return input ?. replace ( / & / g, '&' ) . replace ( / < / g, '<' ) . replace ( / > / g, '>' ) ;
17
+ }
18
+
11
19
/**
12
20
* Poor girl's jsonpath
13
21
*
@@ -59,7 +67,11 @@ export function parseArguments(args, data) {
59
67
* @returns {(data: any, filters: Map<string, function>) => string } a function that takes a data object and returns the processed template
60
68
*/
61
69
export function template ( str ) {
62
- return ( data , filters ) => {
70
+ const defaultFilters = new Map ( ) ;
71
+ let isSafe = false ;
72
+ defaultFilters . set ( 'safe' , ( input ) => { isSafe = true ; return input ; } )
73
+ return ( data , providedFilters ) => {
74
+ const filters = mergeMaps ( defaultFilters || new Map ( ) , providedFilters || new Map ( ) )
63
75
return str . replace ( TEMPLATE_REGEX , ( _ , expr , params , filter , filterParams ) => {
64
76
let result = dataPath ( expr ) ( data ) ;
65
77
const args = parseArguments ( params , data ) ;
@@ -73,7 +85,7 @@ export function template(str) {
73
85
const filterArgs = parseArguments ( filterParams , data ) ;
74
86
result = filters . get ( filter ) ( result , ...filterArgs ) ;
75
87
}
76
- return result ;
88
+ return isSafe ? result : htmlEscape ( result ) ;
77
89
} ) ;
78
90
}
79
91
}
@@ -123,11 +135,12 @@ export async function handleTemplateFile(config, data, inputFile) {
123
135
const l = await handleTemplateFile ( config ,
124
136
{ ...fileData , content : fileContent , layout : null } , layoutFilePath ) ;
125
137
if ( l ) {
126
- fileContent = l . content ; ;
138
+ fileContent = l . content ;
127
139
} else {
128
140
throw new Error ( 'Layout not found:' + layoutFilePath ) ;
129
141
}
130
142
}
131
143
132
144
return { content : fileContent , filename : outputFile } ;
133
145
}
146
+
0 commit comments