@rhinostone/swig-jinja2 2.8.4 → 2.9.0

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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  @rhinostone/swig-jinja2
2
2
  =======================
3
3
 
4
- [![NPM version](https://img.shields.io/npm/v/@rhinostone/swig-jinja2.svg?style=flat)](https://www.npmjs.com/package/@rhinostone/swig-jinja2) [![Socket Badge](https://socket.dev/api/badge/npm/package/@rhinostone/swig-jinja2)](https://socket.dev/npm/package/@rhinostone/swig-jinja2)
4
+ [![NPM version](https://img.shields.io/npm/v/@rhinostone/swig-jinja2.svg?style=flat)](https://www.npmjs.com/package/@rhinostone/swig-jinja2) [![Socket Badge](https://socket.dev/api/badge/npm/package/@rhinostone/swig-jinja2)](https://socket.dev/npm/package/@rhinostone/swig-jinja2) [![OpenSSF Scorecard](https://img.shields.io/ossf-scorecard/github.com/gina-io/swig?label=openssf%20scorecard&style=flat)](https://scorecard.dev/viewer/?uri=github.com/gina-io/swig)
5
5
 
6
6
  Jinja2-syntax frontend for the [@rhinostone/swig-core](https://www.npmjs.com/package/@rhinostone/swig-core) template engine. Part of the multi-flavor architecture introduced in `2.0.0` — see [ROADMAP.md](https://github.com/gina-io/swig/blob/develop/ROADMAP.md) for the release narrative.
7
7
 
package/lib/filters.js CHANGED
@@ -1179,7 +1179,7 @@ exports.slice = function (input, slices, fill) {
1179
1179
  * and `reverse` flips the order.
1180
1180
  *
1181
1181
  * @example
1182
- * {% for k, v in {"b":2,"a":1}|dictsort %}{{ k }}={{ v }};{% endfor %}
1182
+ * {% for p in {"b":2,"a":1}|dictsort %}{{ p[0] }}={{ p[1] }};{% endfor %}
1183
1183
  * // => a=1;b=2;
1184
1184
  *
1185
1185
  * @param {object} input
package/lib/index.js CHANGED
@@ -27,7 +27,7 @@ exports.name = 'jinja2';
27
27
  *
28
28
  * @type {String}
29
29
  */
30
- exports.version = "2.8.4";
30
+ exports.version = "2.9.0";
31
31
 
32
32
  /**
33
33
  * Expression-level parser — Pratt-style recursive descent that consumes
package/lib/lexer.js CHANGED
@@ -108,7 +108,7 @@ var rules = [
108
108
  {
109
109
  type: TYPES.COMPARATOR,
110
110
  regex: [
111
- /^(===|==|\!==|\!=|<=|<|>=|>|in\s)\s*/
111
+ /^(===|==|\!==|\!=|<=|<|>=|>|not\s+in\s|in\s)\s*/
112
112
  ],
113
113
  idx: 1
114
114
  },
package/lib/parser.js CHANGED
@@ -21,6 +21,27 @@ function escapeRegExp(str) {
21
21
  */
22
22
  var _reserved = ['break', 'case', 'catch', 'continue', 'debugger', 'default', 'delete', 'do', 'else', 'finally', 'for', 'function', 'if', 'in', 'instanceof', 'new', 'return', 'switch', 'this', 'throw', 'try', 'typeof', 'var', 'void', 'while', 'with'];
23
23
 
24
+ /**
25
+ * Build the IR of `left in right`, or of `left not in right` when `negate`
26
+ * is set: a BinaryOp `in` flagged with this flavor's name, so swig-core
27
+ * emits Jinja2's membership test (`_utils.isIn`) instead of the JavaScript
28
+ * `in` operator, which tests keys.
29
+ *
30
+ * @param {object} left The needle.
31
+ * @param {object} right The container.
32
+ * @param {boolean} [negate] The `not in` form.
33
+ * @return {object} IRBinaryOp.
34
+ * @private
35
+ */
36
+ function membership(left, right, negate) {
37
+ var node = ir.binaryOp('in', left, right);
38
+ node.membership = 'jinja2';
39
+ if (negate) {
40
+ node.negate = true;
41
+ }
42
+ return node;
43
+ }
44
+
24
45
  /**
25
46
  * Jinja2 expression parser — Pratt-style recursive descent.
26
47
  *
@@ -110,6 +131,9 @@ exports.parseExpr = function (tokens, filters, _posOut) {
110
131
  if (m === '===' || m === '!==' || m === '==' || m === '!=') {
111
132
  return { op: m, prec: 3 };
112
133
  }
134
+ if (/^not\s+in$/.test(m)) {
135
+ return { op: 'not in', prec: 4 };
136
+ }
113
137
  return { op: m, prec: 4 };
114
138
  }
115
139
  if (tok.type === _t.OPERATOR) {
@@ -468,6 +492,8 @@ exports.parseExpr = function (tokens, filters, _posOut) {
468
492
  // Math.floor(a / b). Matches Python `//` for ints and floats,
469
493
  // including negative operands (floors toward negative infinity).
470
494
  left = ir.fnCall(ir.varRef(['Math', 'floor']), [ir.binaryOp('/', left, right)]);
495
+ } else if (info.op === 'in' || info.op === 'not in') {
496
+ left = membership(left, right, info.op === 'not in');
471
497
  } else {
472
498
  left = ir.binaryOp(info.op, left, right);
473
499
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhinostone/swig-jinja2",
3
- "version": "2.8.4",
3
+ "version": "2.9.0",
4
4
  "description": "Jinja2-syntax frontend for the @rhinostone/swig-core template engine. Part of the @rhinostone/swig multi-flavor family.",
5
5
  "keywords": [
6
6
  "template",
@@ -23,7 +23,7 @@
23
23
  "node": ">=12"
24
24
  },
25
25
  "peerDependencies": {
26
- "@rhinostone/swig-core": "2.8.4"
26
+ "@rhinostone/swig-core": "2.9.0"
27
27
  },
28
28
  "publishConfig": {
29
29
  "access": "public"