@rhinostone/swig 2.0.1 → 2.2.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/dist/swig.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! Swig v2.0.1 | https://github.com/gina-io/swig | @license https://github.com/gina-io/swig/blob/master/LICENSE */
1
+ /*! Swig v2.2.0 | https://github.com/gina-io/swig | @license https://github.com/gina-io/swig/blob/master/LICENSE */
2
2
  /*! DateZ (c) 2011 Tomo Universalis | @license https://github.com/ocrybit/DateZ/blob/master/LISENCE */
3
3
  (() => {
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -275,6 +275,49 @@
275
275
  exports.legacyJS = function(js, loc) {
276
276
  return withLoc({ type: "LegacyJS", js }, loc);
277
277
  };
278
+ exports.extendsDeferred = function(path, childBlocks, childIRs, resolveFrom, loc) {
279
+ var node = { type: "ExtendsDeferred", path };
280
+ if (childBlocks !== void 0) {
281
+ node.childBlocks = childBlocks;
282
+ }
283
+ if (childIRs !== void 0) {
284
+ node.childIRs = childIRs;
285
+ }
286
+ if (resolveFrom !== void 0) {
287
+ node.resolveFrom = resolveFrom;
288
+ }
289
+ return withLoc(node, loc);
290
+ };
291
+ exports.includeDeferred = function(path, context, isolated, ignoreMissing, resolveFrom, loc) {
292
+ var node = { type: "IncludeDeferred", path };
293
+ if (context !== void 0) {
294
+ node.context = context;
295
+ }
296
+ if (isolated !== void 0) {
297
+ node.isolated = isolated;
298
+ }
299
+ if (ignoreMissing !== void 0) {
300
+ node.ignoreMissing = ignoreMissing;
301
+ }
302
+ if (resolveFrom !== void 0) {
303
+ node.resolveFrom = resolveFrom;
304
+ }
305
+ return withLoc(node, loc);
306
+ };
307
+ exports.importDeferred = function(path, alias, resolveFrom, loc) {
308
+ var node = { type: "ImportDeferred", path, alias };
309
+ if (resolveFrom !== void 0) {
310
+ node.resolveFrom = resolveFrom;
311
+ }
312
+ return withLoc(node, loc);
313
+ };
314
+ exports.fromImportDeferred = function(path, imports, resolveFrom, loc) {
315
+ var node = { type: "FromImportDeferred", path, imports };
316
+ if (resolveFrom !== void 0) {
317
+ node.resolveFrom = resolveFrom;
318
+ }
319
+ return withLoc(node, loc);
320
+ };
278
321
  exports.literal = function(kind, value, loc) {
279
322
  return withLoc({ type: "Literal", kind, value }, loc);
280
323
  };
@@ -801,32 +844,40 @@
801
844
  exports["default"] = function(input, def) {
802
845
  return typeof input !== "undefined" && (input || typeof input === "number") ? input : def;
803
846
  };
847
+ function escapeHtmlRest(ch) {
848
+ return ch === "<" ? "&lt;" : ch === ">" ? "&gt;" : ch === '"' ? "&quot;" : "&#39;";
849
+ }
804
850
  exports.escape = function(input, type) {
805
- var out = iterateFilter.apply(exports.escape, arguments), inp = input, i = 0, code;
806
- if (out !== void 0) {
807
- return out;
851
+ var t, inp, out, i, code;
852
+ if (input === null || input === void 0) {
853
+ return input;
808
854
  }
809
- if (typeof input !== "string") {
855
+ t = typeof input;
856
+ if (t !== "string") {
857
+ if (t === "object") {
858
+ out = iterateFilter.apply(exports.escape, arguments);
859
+ if (out !== void 0) {
860
+ return out;
861
+ }
862
+ }
810
863
  return input;
811
864
  }
812
- out = "";
813
- switch (type) {
814
- case "js":
815
- inp = inp.replace(/\\/g, "\\u005C");
816
- for (i; i < inp.length; i += 1) {
817
- code = inp.charCodeAt(i);
818
- if (code < 32) {
819
- code = code.toString(16).toUpperCase();
820
- code = code.length < 2 ? "0" + code : code;
821
- out += "\\u00" + code;
822
- } else {
823
- out += inp[i];
824
- }
865
+ if (type === "js") {
866
+ inp = input.replace(/\\/g, "\\u005C");
867
+ out = "";
868
+ for (i = 0; i < inp.length; i += 1) {
869
+ code = inp.charCodeAt(i);
870
+ if (code < 32) {
871
+ code = code.toString(16).toUpperCase();
872
+ code = code.length < 2 ? "0" + code : code;
873
+ out += "\\u00" + code;
874
+ } else {
875
+ out += inp[i];
825
876
  }
826
- return out.replace(/&/g, "\\u0026").replace(/</g, "\\u003C").replace(/>/g, "\\u003E").replace(/\'/g, "\\u0027").replace(/"/g, "\\u0022").replace(/\=/g, "\\u003D").replace(/-/g, "\\u002D").replace(/;/g, "\\u003B");
827
- default:
828
- return inp.replace(/&(?!amp;|lt;|gt;|quot;|#39;)/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
877
+ }
878
+ return out.replace(/&/g, "\\u0026").replace(/</g, "\\u003C").replace(/>/g, "\\u003E").replace(/\'/g, "\\u0027").replace(/"/g, "\\u0022").replace(/\=/g, "\\u003D").replace(/-/g, "\\u002D").replace(/;/g, "\\u003B");
829
879
  }
880
+ return input.replace(/&(?!amp;|lt;|gt;|quot;|#39;)/g, "&amp;").replace(/[<>"']/g, escapeHtmlRest);
830
881
  };
831
882
  exports.e = exports.escape;
832
883
  exports.first = function(input) {
@@ -1345,6 +1396,12 @@
1345
1396
  macroIndexOfJS = '"' + macroParams.join('","') + '"';
1346
1397
  }
1347
1398
  out += "_ctx." + node.name + " = function (" + macroSigJS + ') {\n var _output = "",\n __ctx = _utils.extend({}, _ctx);\n _utils.each(_ctx, function (v, k) {\n if ([' + macroIndexOfJS + "].indexOf(k) !== -1) { delete _ctx[k]; }\n });\n" + macroBodyJS + "\n _ctx = _utils.extend(_ctx, __ctx);\n return _output;\n};\n_ctx." + node.name + ".safe = true;\n";
1399
+ if (options && options.codegenMode === "async") {
1400
+ if (_security.dangerousProps.indexOf(node.name) !== -1) {
1401
+ throw new Error('Macro name "' + node.name + '" is reserved.');
1402
+ }
1403
+ out += "_exports." + node.name + " = _ctx." + node.name + ";\n";
1404
+ }
1348
1405
  return;
1349
1406
  }
1350
1407
  if (node.type === "Parent") {
@@ -1361,6 +1418,24 @@
1361
1418
  return;
1362
1419
  }
1363
1420
  if (node.type === "Block") {
1421
+ if (options && options.codegenMode === "async") {
1422
+ var blockNameJS = JSON.stringify(node.name);
1423
+ out += "if (_blocks && _blocks[" + blockNameJS + "]) {\n";
1424
+ out += " _output += await _blocks[" + blockNameJS + "](_ctx);\n";
1425
+ out += "} else {\n";
1426
+ utils.each(node.body, function(b) {
1427
+ if (b.type === "LegacyJS") {
1428
+ out += b.js;
1429
+ return;
1430
+ }
1431
+ if (b.type === "Text" || b.type === "Raw") {
1432
+ out += '_output += "' + escapeTextValue(b.value) + '";\n';
1433
+ return;
1434
+ }
1435
+ });
1436
+ out += "}\n";
1437
+ return;
1438
+ }
1364
1439
  utils.each(node.body, function(b) {
1365
1440
  if (b.type === "LegacyJS") {
1366
1441
  out += b.js;
@@ -1398,6 +1473,106 @@
1398
1473
  out += (node.ignoreMissing ? " try {\n" : "") + "_output += _swig.compileFile(" + incPathJS + ', {resolveFrom: "' + node.resolveFrom + '"})(' + incSelector + ");\n" + (node.ignoreMissing ? "} catch (e) {}\n" : "");
1399
1474
  return;
1400
1475
  }
1476
+ if (node.type === "IncludeDeferred") {
1477
+ var incdPathJS, incdCtxJS;
1478
+ if (node.path && typeof node.path === "object" && typeof node.path.type === "string") {
1479
+ incdPathJS = exports.emitExpr(node.path);
1480
+ } else {
1481
+ incdPathJS = node.path;
1482
+ }
1483
+ if (node.context !== void 0) {
1484
+ if (typeof node.context === "object" && typeof node.context.type === "string") {
1485
+ incdCtxJS = exports.emitExpr(node.context);
1486
+ } else {
1487
+ incdCtxJS = node.context;
1488
+ }
1489
+ }
1490
+ var incdSelector;
1491
+ if (node.isolated && incdCtxJS) {
1492
+ incdSelector = incdCtxJS;
1493
+ } else if (!incdCtxJS) {
1494
+ incdSelector = "_ctx";
1495
+ } else {
1496
+ incdSelector = "_utils.extend({}, _ctx, " + incdCtxJS + ")";
1497
+ }
1498
+ var incdOpts = '{resolveFrom: "' + (node.resolveFrom || "") + '"}';
1499
+ out += (node.ignoreMissing ? " try {\n" : "") + "_output += (await (await _swig.getTemplate(" + incdPathJS + ", " + incdOpts + "))(" + incdSelector + ")).output;\n" + (node.ignoreMissing ? "} catch (e) {}\n" : "");
1500
+ return;
1501
+ }
1502
+ if (node.type === "ImportDeferred") {
1503
+ if (_security.dangerousProps.indexOf(node.alias) !== -1) {
1504
+ throw new Error('Import alias "' + node.alias + '" is reserved.');
1505
+ }
1506
+ var impdPathJS;
1507
+ if (node.path && typeof node.path === "object" && typeof node.path.type === "string") {
1508
+ impdPathJS = exports.emitExpr(node.path);
1509
+ } else {
1510
+ impdPathJS = node.path;
1511
+ }
1512
+ var impdOpts = '{resolveFrom: "' + (node.resolveFrom || "") + '"}';
1513
+ out += "_ctx." + node.alias + " = (await (await _swig.getTemplate(" + impdPathJS + ", " + impdOpts + "))(_ctx)).exports;\n";
1514
+ return;
1515
+ }
1516
+ if (node.type === "FromImportDeferred") {
1517
+ var fromdImports = node.imports || [];
1518
+ utils.each(fromdImports, function(entry) {
1519
+ if (_security.dangerousProps.indexOf(entry.name) !== -1) {
1520
+ throw new Error('From-import name "' + entry.name + '" is reserved.');
1521
+ }
1522
+ var bindName = entry.alias || entry.name;
1523
+ if (_security.dangerousProps.indexOf(bindName) !== -1) {
1524
+ throw new Error('From-import binding "' + bindName + '" is reserved.');
1525
+ }
1526
+ });
1527
+ var fromdPathJS;
1528
+ if (node.path && typeof node.path === "object" && typeof node.path.type === "string") {
1529
+ fromdPathJS = exports.emitExpr(node.path);
1530
+ } else {
1531
+ fromdPathJS = node.path;
1532
+ }
1533
+ var fromdOpts = '{resolveFrom: "' + (node.resolveFrom || "") + '"}';
1534
+ var fromdBindings = "";
1535
+ utils.each(fromdImports, function(entry) {
1536
+ var bindName = entry.alias || entry.name;
1537
+ fromdBindings += " _ctx." + bindName + ' = _imp["' + entry.name + '"];\n';
1538
+ });
1539
+ out += "await (async function () {\n var _imp = (await (await _swig.getTemplate(" + fromdPathJS + ", " + fromdOpts + "))(_ctx)).exports;\n" + fromdBindings + "})();\n";
1540
+ return;
1541
+ }
1542
+ if (node.type === "ExtendsDeferred") {
1543
+ if (node.childIRs && node.childIRs.length) {
1544
+ out += exports.compile(node.childIRs, parents, options);
1545
+ }
1546
+ out += "var _localChildBlocks = {};\n";
1547
+ if (node.childBlocks) {
1548
+ utils.each(node.childBlocks, function(block, name) {
1549
+ var blockBodyJS = "";
1550
+ utils.each(block.body, function(b) {
1551
+ if (b.type === "LegacyJS") {
1552
+ blockBodyJS += b.js;
1553
+ return;
1554
+ }
1555
+ if (b.type === "Text" || b.type === "Raw") {
1556
+ blockBodyJS += '_output += "' + escapeTextValue(b.value) + '";\n';
1557
+ return;
1558
+ }
1559
+ });
1560
+ out += "_localChildBlocks[" + JSON.stringify(name) + '] = async function (_ctx) {\n var _output = "";\n' + blockBodyJS + " return _output;\n};\n";
1561
+ });
1562
+ }
1563
+ out += "var _mergedBlocks = _utils.extend({}, _localChildBlocks, _blocks || {});\n";
1564
+ var extPathJS;
1565
+ if (node.path && typeof node.path === "object" && typeof node.path.type === "string") {
1566
+ extPathJS = exports.emitExpr(node.path);
1567
+ } else {
1568
+ extPathJS = node.path;
1569
+ }
1570
+ var extOpts = '{resolveFrom: "' + (node.resolveFrom || "") + '"}';
1571
+ out += "var _parentTpl = await _swig.getTemplate(" + extPathJS + ", " + extOpts + ");\n";
1572
+ out += "var _parentResult = await _parentTpl(_ctx, _mergedBlocks);\n";
1573
+ out += "_output = _parentResult.output;\n";
1574
+ return;
1575
+ }
1401
1576
  if (node.type === "With") {
1402
1577
  var withCtxJS;
1403
1578
  if (node.context !== void 0) {
@@ -1575,12 +1750,8 @@
1575
1750
  return build;
1576
1751
  }
1577
1752
  function checkMatchExpr(match) {
1578
- var result;
1579
- function buildDot(ctx) {
1580
- return "(" + checkDotExpr(match, ctx) + " ? " + ctx + match.join(".") + ' : "")';
1581
- }
1582
- result = "(" + checkDotExpr(match, "_ctx.") + " ? " + buildDot("_ctx.") + " : " + buildDot("") + ")";
1583
- return "(" + result + " !== null ? " + result + ' : "" )';
1753
+ var leaf = match.join(".");
1754
+ return "(" + checkDotExpr(match, "_ctx.") + " ? _ctx." + leaf + " : (" + checkDotExpr(match, "") + " ? " + leaf + ' : ""))';
1584
1755
  }
1585
1756
  function emitAccess(node, d) {
1586
1757
  if (node.key && node.key.type === "Literal" && node.key.kind === "string") {
@@ -2652,7 +2823,7 @@
2652
2823
  * @private
2653
2824
  */
2654
2825
  checkMatch: function(match) {
2655
- var temp = match[0], result;
2826
+ var temp = match[0], leaf = match.join(".");
2656
2827
  function checkDot(ctx) {
2657
2828
  var c = ctx + temp, m = match, build = "";
2658
2829
  build = "(typeof " + c + ' !== "undefined" && ' + c + " !== null";
@@ -2666,11 +2837,7 @@
2666
2837
  build += ")";
2667
2838
  return build;
2668
2839
  }
2669
- function buildDot(ctx) {
2670
- return "(" + checkDot(ctx) + " ? " + ctx + match.join(".") + ' : "")';
2671
- }
2672
- result = "(" + checkDot("_ctx.") + " ? " + buildDot("_ctx.") + " : " + buildDot("") + ")";
2673
- return "(" + result + " !== null ? " + result + ' : "" )';
2840
+ return "(" + checkDot("_ctx.") + " ? _ctx." + leaf + " : (" + checkDot("") + " ? " + leaf + ' : ""))';
2674
2841
  }
2675
2842
  };
2676
2843
  exports.TokenParser = TokenParser;
@@ -2834,9 +3001,19 @@
2834
3001
  var require_import = __commonJS({
2835
3002
  "lib/tags/import.js"(exports) {
2836
3003
  var utils = require_utils2();
3004
+ var ir = require_ir();
2837
3005
  var backend = require_backend();
2838
3006
  var _dangerousProps = require_security().dangerousProps;
2839
- exports.compile = function(compiler, args) {
3007
+ exports.compile = function(compiler, args, content, parents, options) {
3008
+ if (options && options.codegenMode === "async") {
3009
+ var asyncAlias = args[args.length - 1];
3010
+ var asyncPath = args[0].path;
3011
+ return ir.importDeferred(
3012
+ ir.literal("string", asyncPath),
3013
+ asyncAlias,
3014
+ options.filename || ""
3015
+ );
3016
+ }
2840
3017
  var ctx = args.pop(), allMacros = utils.map(args, function(arg) {
2841
3018
  return arg.name;
2842
3019
  }).join("|"), out = "_ctx." + ctx + ' = {};\n var _output = "";\n', replacements = utils.map(args, function(arg) {
@@ -2855,27 +3032,31 @@
2855
3032
  return out;
2856
3033
  };
2857
3034
  exports.parse = function(str, line, parser, types, stack, opts, swig2) {
2858
- var compiler = require_parser().compile, parseOpts = { resolveFrom: opts.filename }, compileOpts = utils.extend({}, opts, parseOpts), tokens, ctx;
3035
+ var compiler = require_parser().compile, parseOpts = { resolveFrom: opts.filename }, compileOpts = utils.extend({}, opts, parseOpts), isAsync = !!(opts && opts.codegenMode === "async"), importPath, ctx;
2859
3036
  parser.on(types.STRING, function(token) {
2860
3037
  var self = this;
2861
- if (!tokens) {
2862
- tokens = swig2.parseFile(token.match.replace(/^("|')|("|')$/g, ""), parseOpts).tokens;
2863
- utils.each(tokens, function(token2) {
2864
- var out = "", macroName;
2865
- if (!token2 || token2.name !== "macro" || !token2.compile) {
2866
- return;
2867
- }
2868
- macroName = token2.args[0];
2869
- out += backend.compile([token2.compile(compiler, token2.args, token2.content, [], compileOpts)], [], compileOpts) + "\n";
2870
- self.out.push({ compiled: out, name: macroName });
2871
- });
3038
+ if (importPath !== void 0) {
3039
+ throw new Error("Unexpected string " + token.match + " on line " + line + ".");
3040
+ }
3041
+ importPath = token.match.replace(/^("|')|("|')$/g, "");
3042
+ if (isAsync) {
3043
+ self.out.push({ path: importPath });
2872
3044
  return;
2873
3045
  }
2874
- throw new Error("Unexpected string " + token.match + " on line " + line + ".");
3046
+ var tokens = swig2.parseFile(importPath, parseOpts).tokens;
3047
+ utils.each(tokens, function(token2) {
3048
+ var out = "", macroName;
3049
+ if (!token2 || token2.name !== "macro" || !token2.compile) {
3050
+ return;
3051
+ }
3052
+ macroName = token2.args[0];
3053
+ out += backend.compile([token2.compile(compiler, token2.args, token2.content, [], compileOpts)], [], compileOpts) + "\n";
3054
+ self.out.push({ compiled: out, name: macroName });
3055
+ });
2875
3056
  });
2876
3057
  parser.on(types.VAR, function(token) {
2877
3058
  var self = this;
2878
- if (!tokens || ctx) {
3059
+ if (importPath === void 0 || ctx) {
2879
3060
  throw new Error('Unexpected variable "' + token.match + '" on line ' + line + ".");
2880
3061
  }
2881
3062
  if (token.match === "as") {
@@ -2912,6 +3093,9 @@
2912
3093
  w = void 0;
2913
3094
  }
2914
3095
  }
3096
+ if (options && options.codegenMode === "async") {
3097
+ return ir.includeDeferred(file, w || void 0, !!onlyCtx, !!ignoreMissing, parentFile);
3098
+ }
2915
3099
  return ir.include(file, w || void 0, !!onlyCtx, !!ignoreMissing, parentFile);
2916
3100
  };
2917
3101
  exports.lowerExpr = function(parser, tokens) {
@@ -3789,6 +3973,155 @@
3789
3973
  }
3790
3974
  });
3791
3975
 
3976
+ // lib/async/pre-walker.js
3977
+ var require_pre_walker = __commonJS({
3978
+ "lib/async/pre-walker.js"(exports) {
3979
+ var utils = require_utils2();
3980
+ function escapeRegExp(str) {
3981
+ return str.replace(/[\-\/\\\^$*+?.()|\[\]{}]/g, "\\$&");
3982
+ }
3983
+ function buildSplitter(controls) {
3984
+ var anyChar = "[\\s\\S]*?", varOpen = escapeRegExp(controls.varControls[0]), varClose = escapeRegExp(controls.varControls[1]), tagOpen = escapeRegExp(controls.tagControls[0]), tagClose = escapeRegExp(controls.tagControls[1]), cmtOpen = escapeRegExp(controls.cmtControls[0]), cmtClose = escapeRegExp(controls.cmtControls[1]);
3985
+ return new RegExp(
3986
+ "(" + tagOpen + anyChar + tagClose + "|" + varOpen + anyChar + varClose + "|" + cmtOpen + anyChar + cmtClose + ")"
3987
+ );
3988
+ }
3989
+ function stripTagBody(chunk, tagOpen, tagClose) {
3990
+ var body = chunk.substr(tagOpen.length, chunk.length - tagOpen.length - tagClose.length);
3991
+ if (body.charAt(0) === "-") {
3992
+ body = body.substr(1);
3993
+ }
3994
+ if (body.charAt(body.length - 1) === "-") {
3995
+ body = body.substr(0, body.length - 1);
3996
+ }
3997
+ return body.replace(/^\s+|\s+$/g, "");
3998
+ }
3999
+ exports.scan = function(source, opts) {
4000
+ source = source.replace(/\r\n/g, "\n");
4001
+ var splitter = buildSplitter(opts), tagOpen = opts.tagControls[0], tagClose = opts.tagControls[1], rawTag = opts.rawTag, endRawTag = "end" + rawTag, keywordRegex = new RegExp(
4002
+ "^(" + opts.keywords.join("|") + `)\\s+["\\']([^"\\']+)["\\']`
4003
+ ), chunks = source.split(splitter), results = [], inRaw = false, i, chunk, body, name, m;
4004
+ for (i = 0; i < chunks.length; i += 1) {
4005
+ chunk = chunks[i];
4006
+ if (typeof chunk !== "string" || !chunk) {
4007
+ continue;
4008
+ }
4009
+ if (!utils.startsWith(chunk, tagOpen) || !utils.endsWith(chunk, tagClose)) {
4010
+ continue;
4011
+ }
4012
+ body = stripTagBody(chunk, tagOpen, tagClose);
4013
+ name = body.split(/\s+/)[0];
4014
+ if (name === rawTag) {
4015
+ inRaw = true;
4016
+ continue;
4017
+ }
4018
+ if (name === endRawTag) {
4019
+ inRaw = false;
4020
+ continue;
4021
+ }
4022
+ if (inRaw) {
4023
+ continue;
4024
+ }
4025
+ m = keywordRegex.exec(body);
4026
+ if (m) {
4027
+ results.push({ kind: m[1], path: m[2] });
4028
+ }
4029
+ }
4030
+ return results;
4031
+ };
4032
+ exports.walk = function(entryPath, loader, scanOpts) {
4033
+ var memMap = {};
4034
+ var pending = {};
4035
+ return new Promise(function(resolve, reject) {
4036
+ var inFlight = 0;
4037
+ var queue = [];
4038
+ var hasError = false;
4039
+ function enqueue(path) {
4040
+ if (memMap.hasOwnProperty(path) || pending[path]) {
4041
+ return;
4042
+ }
4043
+ pending[path] = true;
4044
+ queue.push(path);
4045
+ }
4046
+ function drain() {
4047
+ while (queue.length > 0 && !hasError) {
4048
+ var path = queue.shift();
4049
+ inFlight += 1;
4050
+ startLoad(path);
4051
+ }
4052
+ if (inFlight === 0 && !hasError && queue.length === 0) {
4053
+ resolve(memMap);
4054
+ }
4055
+ }
4056
+ function startLoad(resolvedPath) {
4057
+ loader.load(resolvedPath, function(err, src) {
4058
+ if (hasError) {
4059
+ return;
4060
+ }
4061
+ if (err) {
4062
+ hasError = true;
4063
+ reject(err);
4064
+ return;
4065
+ }
4066
+ if (typeof src !== "string") {
4067
+ hasError = true;
4068
+ reject(new Error('Async loader returned non-string source for "' + resolvedPath + '"'));
4069
+ return;
4070
+ }
4071
+ memMap[resolvedPath] = src;
4072
+ var targets;
4073
+ try {
4074
+ targets = exports.scan(src, scanOpts);
4075
+ } catch (e) {
4076
+ hasError = true;
4077
+ reject(e);
4078
+ return;
4079
+ }
4080
+ var i, resolvedChild;
4081
+ for (i = 0; i < targets.length; i += 1) {
4082
+ try {
4083
+ resolvedChild = loader.resolve(targets[i].path, resolvedPath);
4084
+ } catch (e) {
4085
+ hasError = true;
4086
+ reject(e);
4087
+ return;
4088
+ }
4089
+ enqueue(resolvedChild);
4090
+ }
4091
+ inFlight -= 1;
4092
+ drain();
4093
+ });
4094
+ }
4095
+ enqueue(entryPath);
4096
+ drain();
4097
+ });
4098
+ };
4099
+ exports.makeMemoryWrapper = function(userLoader, memMap) {
4100
+ return {
4101
+ resolve: function(to, from) {
4102
+ return userLoader.resolve(to, from);
4103
+ },
4104
+ load: function(id, cb) {
4105
+ var src = memMap[id];
4106
+ if (typeof src !== "string") {
4107
+ var err = new Error('Pre-walked map missing path: "' + id + '"');
4108
+ if (cb) {
4109
+ cb(err);
4110
+ return;
4111
+ }
4112
+ throw err;
4113
+ }
4114
+ if (cb) {
4115
+ cb(null, src);
4116
+ return;
4117
+ }
4118
+ return src;
4119
+ }
4120
+ };
4121
+ };
4122
+ }
4123
+ });
4124
+
3792
4125
  // packages/swig-core/lib/cache.js
3793
4126
  var require_cache = __commonJS({
3794
4127
  "packages/swig-core/lib/cache.js"(exports) {
@@ -3822,8 +4155,11 @@
3822
4155
  var require_engine = __commonJS({
3823
4156
  "packages/swig-core/lib/engine.js"(exports) {
3824
4157
  var utils = require_utils();
4158
+ var ir = require_ir();
3825
4159
  var backend = require_backend();
3826
4160
  var cache = require_cache();
4161
+ var AsyncFunction = Object.getPrototypeOf(async function() {
4162
+ }).constructor;
3827
4163
  function efn() {
3828
4164
  return "";
3829
4165
  }
@@ -3850,6 +4186,45 @@
3850
4186
  }
3851
4187
  });
3852
4188
  };
4189
+ function buildExtendsDeferred(tokens, options) {
4190
+ var childBlocks = {};
4191
+ var childIRs = [];
4192
+ utils.each(tokens.blocks, function(blockToken) {
4193
+ var args = blockToken.args ? blockToken.args.slice(0) : [];
4194
+ var content = blockToken.content ? blockToken.content.slice(0) : [];
4195
+ if (blockToken.name === "block") {
4196
+ var blockName = args.join("");
4197
+ var blockIR = blockToken.compile(backend.compile, args, content, [], options, blockName, blockToken);
4198
+ if (blockIR && typeof blockIR === "object" && typeof blockIR.type === "string") {
4199
+ childBlocks[blockName] = blockIR;
4200
+ }
4201
+ return;
4202
+ }
4203
+ var result = blockToken.compile(backend.compile, args, content, [], options, void 0, blockToken);
4204
+ if (result === void 0 || result === null || result === "") {
4205
+ return;
4206
+ }
4207
+ if (typeof result === "string") {
4208
+ childIRs.push(ir.legacyJS(result));
4209
+ return;
4210
+ }
4211
+ if (utils.isArray(result)) {
4212
+ utils.each(result, function(n) {
4213
+ childIRs.push(n);
4214
+ });
4215
+ return;
4216
+ }
4217
+ if (typeof result === "object" && typeof result.type === "string") {
4218
+ childIRs.push(result);
4219
+ }
4220
+ });
4221
+ return ir.extendsDeferred(
4222
+ ir.literal("string", tokens.parent),
4223
+ childBlocks,
4224
+ childIRs,
4225
+ options.filename || ""
4226
+ );
4227
+ }
3853
4228
  exports.getParents = function(tokens, options, deps) {
3854
4229
  var parentName = tokens.parent, parentFiles = [], parents = [], parentFile, parent, l;
3855
4230
  while (parentName) {
@@ -3874,14 +4249,12 @@
3874
4249
  return parents;
3875
4250
  };
3876
4251
  exports.buildTemplateFunction = function(tokens, parents, options) {
3877
- return new Function(
3878
- "_swig",
3879
- "_ctx",
3880
- "_filters",
3881
- "_utils",
3882
- "_fn",
3883
- ' var _ext = _swig.extensions,\n _output = "";\n' + backend.compile(tokens, parents, options) + "\n return _output;\n"
3884
- );
4252
+ if (options && options.codegenMode === "async") {
4253
+ var asyncBody = ' var _ext = _swig.extensions,\n _output = "",\n _exports = {};\n' + backend.compile(tokens, parents, options) + "\n return { output: _output, exports: _exports };\n";
4254
+ return new AsyncFunction("_swig", "_ctx", "_filters", "_utils", "_fn", "_blocks", asyncBody);
4255
+ }
4256
+ var body = ' var _ext = _swig.extensions,\n _output = "";\n' + backend.compile(tokens, parents, options) + "\n return _output;\n";
4257
+ return new Function("_swig", "_ctx", "_filters", "_utils", "_fn", body);
3885
4258
  };
3886
4259
  exports.install = function(self, frontend) {
3887
4260
  var parser = frontend.parser, tags = utils.extend({}, frontend.tags), filters = utils.extend({}, frontend.filters), validateOptions = frontend.validateOptions, onCompileError = frontend.onCompileError;
@@ -3959,10 +4332,16 @@
3959
4332
  return self.parse(src, options);
3960
4333
  };
3961
4334
  self.precompile = function(source, options) {
3962
- var tokens = self.parse(source, options), parents = getParentsInternal(tokens, options), tpl;
3963
- if (parents.length) {
3964
- tokens.tokens = exports.remapBlocks(tokens.blocks, parents[0].tokens);
3965
- exports.importNonBlocks(tokens.blocks, tokens.tokens);
4335
+ var tokens = self.parse(source, options), parents, tpl;
4336
+ if (options && options.codegenMode === "async" && tokens.parent) {
4337
+ parents = [];
4338
+ tokens.tokens = [buildExtendsDeferred(tokens, options)];
4339
+ } else {
4340
+ parents = getParentsInternal(tokens, options);
4341
+ if (parents.length) {
4342
+ tokens.tokens = exports.remapBlocks(tokens.blocks, parents[0].tokens);
4343
+ exports.importNonBlocks(tokens.blocks, tokens.tokens);
4344
+ }
3966
4345
  }
3967
4346
  try {
3968
4347
  tpl = exports.buildTemplateFunction(tokens, parents, options);
@@ -3979,7 +4358,7 @@
3979
4358
  context = getLocals(options);
3980
4359
  contextLength = utils.keys(context).length;
3981
4360
  pre = self.precompile(source, options);
3982
- function compiled(locals) {
4361
+ function compiled(locals, blocks) {
3983
4362
  var lcls;
3984
4363
  if (locals && contextLength) {
3985
4364
  lcls = utils.extend({}, context, locals);
@@ -3990,7 +4369,7 @@
3990
4369
  } else {
3991
4370
  lcls = {};
3992
4371
  }
3993
- return pre.tpl(self, lcls, filters, utils, efn);
4372
+ return pre.tpl(self, lcls, filters, utils, efn, blocks);
3994
4373
  }
3995
4374
  utils.extend(compiled, pre.tokens);
3996
4375
  if (key) {
@@ -4035,11 +4414,65 @@
4035
4414
  src = self.options.loader.load(pathname);
4036
4415
  return self.compile(src, options);
4037
4416
  };
4417
+ self.getTemplate = function(pathname, options) {
4418
+ options = options || {};
4419
+ var resolved;
4420
+ try {
4421
+ resolved = self.options.loader.resolve(pathname, options.resolveFrom);
4422
+ } catch (e) {
4423
+ return Promise.reject(e);
4424
+ }
4425
+ var compileOpts = utils.extend({}, options, {
4426
+ filename: options.filename || resolved,
4427
+ codegenMode: "async",
4428
+ cache: false
4429
+ });
4430
+ return new Promise(function(resolve, reject) {
4431
+ function onLoaded(err, src2) {
4432
+ if (err) {
4433
+ reject(err);
4434
+ return;
4435
+ }
4436
+ var compiled;
4437
+ try {
4438
+ compiled = self.compile(src2, compileOpts);
4439
+ } catch (err2) {
4440
+ reject(err2);
4441
+ return;
4442
+ }
4443
+ resolve(compiled);
4444
+ }
4445
+ if (self.options.loader.load.length >= 2) {
4446
+ try {
4447
+ self.options.loader.load(resolved, onLoaded);
4448
+ } catch (e) {
4449
+ onLoaded(e);
4450
+ }
4451
+ } else {
4452
+ var src;
4453
+ try {
4454
+ src = self.options.loader.load(resolved);
4455
+ } catch (e) {
4456
+ onLoaded(e);
4457
+ return;
4458
+ }
4459
+ onLoaded(null, src);
4460
+ }
4461
+ });
4462
+ };
4038
4463
  self.render = function(source, options) {
4039
4464
  return self.compile(source, options)();
4040
4465
  };
4041
4466
  self.renderFile = function(pathName, locals, cb) {
4042
4467
  if (cb) {
4468
+ if (self.options.loader && self.options.loader.async === true) {
4469
+ self.getTemplate(pathName).then(function(fn) {
4470
+ return fn(locals);
4471
+ }).then(function(result) {
4472
+ cb(null, result.output);
4473
+ }).catch(cb);
4474
+ return;
4475
+ }
4043
4476
  self.compileFile(pathName, {}, function(err, fn) {
4044
4477
  var result;
4045
4478
  if (err) {
@@ -4078,8 +4511,9 @@
4078
4511
  var parser = require_parser();
4079
4512
  var dateformatter = require_dateformatter2();
4080
4513
  var loaders = require_loaders2();
4514
+ var preWalker = require_pre_walker();
4081
4515
  var engine = require_engine();
4082
- exports.version = "2.0.1";
4516
+ exports.version = "2.2.0";
4083
4517
  var defaultOptions = {
4084
4518
  autoescape: true,
4085
4519
  varControls: ["{{", "}}"],
@@ -4182,6 +4616,94 @@
4182
4616
  utils.throwError(err, null, options.filename);
4183
4617
  }
4184
4618
  });
4619
+ var self = this;
4620
+ function buildScanOpts() {
4621
+ return {
4622
+ varControls: self.options.varControls,
4623
+ tagControls: self.options.tagControls,
4624
+ cmtControls: self.options.cmtControls,
4625
+ rawTag: "raw",
4626
+ keywords: ["extends", "include", "import"]
4627
+ };
4628
+ }
4629
+ this.renderFileAsync = function(pathName, locals, cb) {
4630
+ if (typeof locals === "function") {
4631
+ cb = locals;
4632
+ locals = void 0;
4633
+ }
4634
+ var loader = self.options.loader;
4635
+ var entry;
4636
+ try {
4637
+ entry = loader.resolve(pathName);
4638
+ } catch (e) {
4639
+ cb(e);
4640
+ return;
4641
+ }
4642
+ preWalker.walk(entry, loader, buildScanOpts()).then(function(memMap) {
4643
+ var memWrapper = preWalker.makeMemoryWrapper(loader, memMap);
4644
+ var origLoader = self.options.loader;
4645
+ self.options.loader = memWrapper;
4646
+ var output, error;
4647
+ try {
4648
+ output = self.renderFile(entry, locals);
4649
+ } catch (e) {
4650
+ error = e;
4651
+ }
4652
+ self.options.loader = origLoader;
4653
+ if (error) {
4654
+ cb(error);
4655
+ return;
4656
+ }
4657
+ cb(null, output);
4658
+ }, function(err) {
4659
+ cb(err);
4660
+ });
4661
+ };
4662
+ this.compileFileAsync = function(pathName, options, cb) {
4663
+ if (typeof options === "function") {
4664
+ cb = options;
4665
+ options = {};
4666
+ }
4667
+ var loader = self.options.loader;
4668
+ var entry;
4669
+ try {
4670
+ entry = loader.resolve(pathName);
4671
+ } catch (e) {
4672
+ cb(e);
4673
+ return;
4674
+ }
4675
+ preWalker.walk(entry, loader, buildScanOpts()).then(function(memMap) {
4676
+ var memWrapper = preWalker.makeMemoryWrapper(loader, memMap);
4677
+ var origLoader = self.options.loader;
4678
+ self.options.loader = memWrapper;
4679
+ var compiled, error;
4680
+ try {
4681
+ compiled = self.compileFile(entry, options);
4682
+ } catch (e) {
4683
+ error = e;
4684
+ }
4685
+ self.options.loader = origLoader;
4686
+ if (error) {
4687
+ cb(error);
4688
+ return;
4689
+ }
4690
+ var wrapped = function(locals) {
4691
+ var origInner = self.options.loader;
4692
+ self.options.loader = memWrapper;
4693
+ try {
4694
+ var output = compiled(locals);
4695
+ self.options.loader = origInner;
4696
+ return output;
4697
+ } catch (e) {
4698
+ self.options.loader = origInner;
4699
+ throw e;
4700
+ }
4701
+ };
4702
+ cb(null, wrapped);
4703
+ }, function(err) {
4704
+ cb(err);
4705
+ });
4706
+ };
4185
4707
  };
4186
4708
  defaultInstance = new exports.Swig();
4187
4709
  exports.setFilter = defaultInstance.setFilter;
@@ -4191,8 +4713,10 @@
4191
4713
  exports.precompile = defaultInstance.precompile;
4192
4714
  exports.compile = defaultInstance.compile;
4193
4715
  exports.compileFile = defaultInstance.compileFile;
4716
+ exports.compileFileAsync = defaultInstance.compileFileAsync;
4194
4717
  exports.render = defaultInstance.render;
4195
4718
  exports.renderFile = defaultInstance.renderFile;
4719
+ exports.renderFileAsync = defaultInstance.renderFileAsync;
4196
4720
  exports.run = defaultInstance.run;
4197
4721
  exports.invalidateCache = defaultInstance.invalidateCache;
4198
4722
  exports.loaders = loaders;
@@ -4273,10 +4797,13 @@
4273
4797
  * compiled VarRef body relies on. @private
4274
4798
  */
4275
4799
  /*!
4276
- * Replica of `TokenParser.prototype.checkMatch`. Kept as a local private
4277
- * helper rather than imported from tokenparser.js because (a) it is a
4278
- * pure function of its argument and (b) the backend must not acquire a
4279
- * runtime dependency on the TokenParser module (which is a specific
4800
+ * Build the dot-path emit. `(checkDot_ctx ? _ctx.<path> : (checkDot_closure
4801
+ * ? <path> : ""))` checks the `_ctx.<path>` walk first, falls back to a
4802
+ * bare-closure walk (covers macro params, host-globals like `Math`), and
4803
+ * coerces a missing path to `""` for safe interpolation. Kept as a local
4804
+ * private helper rather than imported from tokenparser.js because (a) it
4805
+ * is a pure function of its argument and (b) the backend must not acquire
4806
+ * a runtime dependency on the TokenParser module (which is a specific
4280
4807
  * frontend concern, not a shared-backend one). @private
4281
4808
  */
4282
4809
  /*!
@@ -4316,6 +4843,21 @@
4316
4843
  * Loop over the source, split via the tag/var/comment regular expression splitter.
4317
4844
  * Send each chunk to the appropriate parser.
4318
4845
  */
4846
+ /*!
4847
+ * Makes a string safe for a regular expression. Mirrors lib/parser.js.
4848
+ * @private
4849
+ */
4850
+ /*!
4851
+ * Build the splitter regex from the controls trio. Mirrors the regex that
4852
+ * parser.parse() builds at parse-time so the pre-walker chunks the same
4853
+ * way the real parser would.
4854
+ * @private
4855
+ */
4856
+ /*!
4857
+ * Strip tag controls and optional whitespace-control markers from a tag
4858
+ * chunk, returning the trimmed tag body (e.g. `extends "x.html"`).
4859
+ * @private
4860
+ */
4319
4861
  /*!
4320
4862
  * Export methods publicly
4321
4863
  */