@rhinostone/swig-twig 2.8.1 → 2.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +20 -3
- package/lib/parser.js +2 -2
- package/lib/tags/apply.js +1 -1
- package/lib/tags/block.js +1 -1
- package/lib/tags/for.js +1 -1
- package/lib/tags/from.js +1 -1
- package/lib/tags/import.js +1 -1
- package/lib/tags/macro.js +1 -1
- package/lib/tags/set.js +6 -5
- package/package.json +2 -2
package/lib/index.js
CHANGED
|
@@ -19,6 +19,16 @@ var utils = require('@rhinostone/swig-core/lib/utils'),
|
|
|
19
19
|
|
|
20
20
|
exports.name = 'twig';
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Package version number as a string. The packages of the family are
|
|
24
|
+
* released together, so they share one version.
|
|
25
|
+
* @example
|
|
26
|
+
* if (twig.version === "2.8.2") { ... }
|
|
27
|
+
*
|
|
28
|
+
* @type {String}
|
|
29
|
+
*/
|
|
30
|
+
exports.version = "2.8.2";
|
|
31
|
+
|
|
22
32
|
/**
|
|
23
33
|
* Expression-level parser — Pratt-style recursive descent that consumes
|
|
24
34
|
* Twig lexer tokens and returns swig-core IRExpr nodes.
|
|
@@ -75,7 +85,7 @@ function validateOptions(options) {
|
|
|
75
85
|
if (!options.hasOwnProperty(key)) {
|
|
76
86
|
return;
|
|
77
87
|
}
|
|
78
|
-
if (!utils.isArray(options[key]) || options[key].length !== 2) {
|
|
88
|
+
if (!utils.isArray(options[key]) || options[key].length !== 2 || typeof options[key][0] !== 'string' || typeof options[key][1] !== 'string') {
|
|
79
89
|
throw new Error('Option "' + key + '" must be an array containing 2 different control strings.');
|
|
80
90
|
}
|
|
81
91
|
if (options[key][0] === options[key][1]) {
|
|
@@ -83,7 +93,7 @@ function validateOptions(options) {
|
|
|
83
93
|
}
|
|
84
94
|
utils.each(options[key], function (a, i) {
|
|
85
95
|
if (a.length < 2) {
|
|
86
|
-
throw new Error('Option "' + key + '" ' + ((i) ? '
|
|
96
|
+
throw new Error('Option "' + key + '" ' + ((i) ? 'close ' : 'open ') + 'control must be at least 2 characters. Saw "' + a + '" instead.');
|
|
87
97
|
}
|
|
88
98
|
});
|
|
89
99
|
});
|
|
@@ -151,7 +161,14 @@ exports.Twig = function (opts) {
|
|
|
151
161
|
filters: _filters,
|
|
152
162
|
validateOptions: validateOptions,
|
|
153
163
|
onCompileError: function (err, options) {
|
|
154
|
-
|
|
164
|
+
var filename = options && options.filename;
|
|
165
|
+
// An error with no file name to add, or one whose message already
|
|
166
|
+
// names the file (a tag's own throwError does), is rethrown
|
|
167
|
+
// unchanged instead of being wrapped a second time.
|
|
168
|
+
if (err instanceof Error && (!filename || err.message.indexOf(' in file ' + filename) !== -1)) {
|
|
169
|
+
throw err;
|
|
170
|
+
}
|
|
171
|
+
utils.throwError(err, null, filename);
|
|
155
172
|
}
|
|
156
173
|
});
|
|
157
174
|
|
package/lib/parser.js
CHANGED
|
@@ -85,12 +85,12 @@ exports.parseExpr = function (tokens, filters, _posOut) {
|
|
|
85
85
|
|
|
86
86
|
function guardSegment(segment) {
|
|
87
87
|
if (_dangerousProps.indexOf(segment) !== -1) {
|
|
88
|
-
bail('Unsafe access to "' + segment + '" is not allowed in templates (
|
|
88
|
+
bail('Unsafe access to "' + segment + '" is not allowed in templates (prototype-chain guard)');
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
function guardBracketString(value) {
|
|
92
92
|
if (_dangerousProps.indexOf(value) !== -1) {
|
|
93
|
-
bail('Unsafe access to "' + value + '" via bracket notation is not allowed in templates (
|
|
93
|
+
bail('Unsafe access to "' + value + '" via bracket notation is not allowed in templates (prototype-chain guard)');
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
|
package/lib/tags/apply.js
CHANGED
|
@@ -109,7 +109,7 @@ exports.parse = function (str, line, parser, types, stack, opts, swig, token) {
|
|
|
109
109
|
|
|
110
110
|
function checkName(name) {
|
|
111
111
|
if (_dangerousProps.indexOf(name) !== -1) {
|
|
112
|
-
utils.throwError('Unsafe filter name "' + name + '" is not allowed (
|
|
112
|
+
utils.throwError('Unsafe filter name "' + name + '" is not allowed (prototype-chain guard)', line, opts.filename);
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
|
package/lib/tags/block.js
CHANGED
|
@@ -66,7 +66,7 @@ exports.parse = function (str, line, parser, types, stack, opts, swig, token) {
|
|
|
66
66
|
utils.throwError('Block name "' + nameTok.match + '" must be a bare identifier', line, opts.filename);
|
|
67
67
|
}
|
|
68
68
|
if (_dangerousProps.indexOf(nameTok.match) !== -1) {
|
|
69
|
-
utils.throwError('Unsafe block name "' + nameTok.match + '" is not allowed (
|
|
69
|
+
utils.throwError('Unsafe block name "' + nameTok.match + '" is not allowed (prototype-chain guard)', line, opts.filename);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
pos += 1;
|
package/lib/tags/for.js
CHANGED
|
@@ -76,7 +76,7 @@ exports.parse = function (str, line, parser, types, stack, opts, swig, token) {
|
|
|
76
76
|
utils.throwError('Loop variable "' + tok.match + '" must be a bare identifier in "for" tag', line, opts.filename);
|
|
77
77
|
}
|
|
78
78
|
if (_dangerousProps.indexOf(tok.match) !== -1) {
|
|
79
|
-
utils.throwError('Unsafe loop variable "' + tok.match + '" is not allowed (
|
|
79
|
+
utils.throwError('Unsafe loop variable "' + tok.match + '" is not allowed (prototype-chain guard)', line, opts.filename);
|
|
80
80
|
}
|
|
81
81
|
return tok.match;
|
|
82
82
|
}
|
package/lib/tags/from.js
CHANGED
|
@@ -88,7 +88,7 @@ exports.parse = function (str, line, parser, types, stack, opts, swig, token) {
|
|
|
88
88
|
utils.throwError(role + ' "' + name + '" must be a bare identifier in "from" tag', line, opts.filename);
|
|
89
89
|
}
|
|
90
90
|
if (_dangerousProps.indexOf(name) !== -1) {
|
|
91
|
-
utils.throwError('Unsafe ' + role.toLowerCase() + ' "' + name + '" is not allowed (
|
|
91
|
+
utils.throwError('Unsafe ' + role.toLowerCase() + ' "' + name + '" is not allowed (prototype-chain guard)', line, opts.filename);
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
package/lib/tags/import.js
CHANGED
|
@@ -106,7 +106,7 @@ exports.parse = function (str, line, parser, types, stack, opts, swig, token) {
|
|
|
106
106
|
utils.throwError('Import alias "' + aliasTok.match + '" must be a bare identifier in "import" tag', line, opts.filename);
|
|
107
107
|
}
|
|
108
108
|
if (_dangerousProps.indexOf(aliasTok.match) !== -1) {
|
|
109
|
-
utils.throwError('Unsafe import alias "' + aliasTok.match + '" is not allowed (
|
|
109
|
+
utils.throwError('Unsafe import alias "' + aliasTok.match + '" is not allowed (prototype-chain guard)', line, opts.filename);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
if (peek()) {
|
package/lib/tags/macro.js
CHANGED
|
@@ -76,7 +76,7 @@ exports.parse = function (str, line, parser, types, stack, opts, swig, token) {
|
|
|
76
76
|
utils.throwError(role + ' "' + name + '" must be a bare identifier in "macro" tag', line, opts.filename);
|
|
77
77
|
}
|
|
78
78
|
if (_dangerousProps.indexOf(name) !== -1) {
|
|
79
|
-
utils.throwError('Unsafe ' + role.toLowerCase() + ' "' + name + '" is not allowed (
|
|
79
|
+
utils.throwError('Unsafe ' + role.toLowerCase() + ' "' + name + '" is not allowed (prototype-chain guard)', line, opts.filename);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
|
package/lib/tags/set.js
CHANGED
|
@@ -84,17 +84,18 @@ exports.parse = function (str, line, parser, types, stack, opts, swig, token) {
|
|
|
84
84
|
var path = lhsTok.match.split('.');
|
|
85
85
|
utils.each(path, function (segment) {
|
|
86
86
|
if (_dangerousProps.indexOf(segment) !== -1) {
|
|
87
|
-
utils.throwError('Unsafe assignment to "' + segment + '" is not allowed (
|
|
87
|
+
utils.throwError('Unsafe assignment to "' + segment + '" is not allowed (prototype-chain guard)', line, opts.filename);
|
|
88
88
|
}
|
|
89
89
|
});
|
|
90
90
|
|
|
91
|
-
// DOTKEY tail — the Twig lexer
|
|
92
|
-
//
|
|
93
|
-
//
|
|
91
|
+
// DOTKEY tail — the Twig lexer folds `foo.bar` into one VAR match, but a
|
|
92
|
+
// dot after whitespace (`foo .bar`) lexes as its own DOTKEY token, so this
|
|
93
|
+
// loop runs today; it also keeps the tag safe if a future lexer splits
|
|
94
|
+
// `foo.bar` into VAR + DOTKEY.
|
|
94
95
|
while (peek() && peek().type === types.DOTKEY) {
|
|
95
96
|
var dk = consume();
|
|
96
97
|
if (_dangerousProps.indexOf(dk.match) !== -1) {
|
|
97
|
-
utils.throwError('Unsafe assignment to "' + dk.match + '" is not allowed (
|
|
98
|
+
utils.throwError('Unsafe assignment to "' + dk.match + '" is not allowed (prototype-chain guard)', line, opts.filename);
|
|
98
99
|
}
|
|
99
100
|
path.push(dk.match);
|
|
100
101
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rhinostone/swig-twig",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.2",
|
|
4
4
|
"description": "Twig-syntax frontend for the @rhinostone/swig-core template engine. Part of the @rhinostone/swig multi-flavor family.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"template",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"node": ">=12"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
|
-
"@rhinostone/swig-core": "2.8.
|
|
25
|
+
"@rhinostone/swig-core": "2.8.2"
|
|
26
26
|
},
|
|
27
27
|
"publishConfig": {
|
|
28
28
|
"access": "public"
|