1 | 'use strict'
|
2 |
|
3 | const vm = require('vm')
|
4 |
|
5 | const htmlRegexp = /[&<>"']/g
|
6 | const htmlSymbols = {
|
7 | '&': '&',
|
8 | '<': '<',
|
9 | '>': '>',
|
10 | '"': '"',
|
11 | '\'': '''
|
12 | }
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 | function escapeHTML (unescaped) {
|
24 | return unescaped.replace(htmlRegexp, (match) => htmlSymbols[match])
|
25 | }
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 | function placeholders (input, ctx, settings, opts) {
|
40 |
|
41 |
|
42 | for (let i = 0; i < settings.length; i++) {
|
43 | const matches = input.match(settings[i].regexp)
|
44 |
|
45 | if (!matches) continue
|
46 |
|
47 | const delimiters = settings[i].text
|
48 |
|
49 | for (let j = 0; j < matches.length; j++) {
|
50 | const match = matches[j]
|
51 |
|
52 | const expression = match.substring(delimiters[0].length, match.length - delimiters[1].length).trim()
|
53 |
|
54 |
|
55 | let value
|
56 |
|
57 | if (/\W+/.test(expression)) {
|
58 | try {
|
59 | value = vm.runInContext(expression, ctx)
|
60 | } catch (error) {
|
61 | if (opts.strictMode) {
|
62 | throw new SyntaxError(error)
|
63 | }
|
64 | }
|
65 | } else if (Object.prototype.hasOwnProperty.call(ctx, expression)) {
|
66 | value = ctx[expression]
|
67 | }
|
68 |
|
69 |
|
70 | if (value === null || value === undefined) {
|
71 | if (opts.missingLocal === undefined) {
|
72 | if (opts.strictMode) {
|
73 | throw new ReferenceError(`'${expression}' is not defined`)
|
74 | }
|
75 | } else if (typeof opts.missingLocal === 'string') {
|
76 | value = opts.missingLocal.replace('{local}', match)
|
77 | }
|
78 | }
|
79 |
|
80 | if (settings[i].escape && typeof value === 'string') {
|
81 | value = escapeHTML(value)
|
82 | } else if (typeof value === 'object') {
|
83 | value = JSON.stringify(value)
|
84 | }
|
85 |
|
86 |
|
87 | input = input.replace(match, value)
|
88 | }
|
89 | }
|
90 |
|
91 | return input
|
92 | }
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 | module.exports = placeholders
|