easy-template-x 4.1.0 → 4.1.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.
@@ -5,49 +5,6 @@ var getProp = require('lodash.get');
5
5
  var JSON5 = require('json5');
6
6
  var JSZip = require('jszip');
7
7
 
8
- function _interopNamespaceDefault(e) {
9
- var n = Object.create(null);
10
- if (e) {
11
- Object.keys(e).forEach(function (k) {
12
- if (k !== 'default') {
13
- var d = Object.getOwnPropertyDescriptor(e, k);
14
- Object.defineProperty(n, k, d.get ? d : {
15
- enumerable: true,
16
- get: function () { return e[k]; }
17
- });
18
- }
19
- });
20
- }
21
- n.default = e;
22
- return Object.freeze(n);
23
- }
24
-
25
- var JSON5__namespace = /*#__PURE__*/_interopNamespaceDefault(JSON5);
26
- var JSZip__namespace = /*#__PURE__*/_interopNamespaceDefault(JSZip);
27
-
28
- function _defineProperty(e, r, t) {
29
- return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
30
- value: t,
31
- enumerable: !0,
32
- configurable: !0,
33
- writable: !0
34
- }) : e[r] = t, e;
35
- }
36
- function _toPrimitive(t, r) {
37
- if ("object" != typeof t || !t) return t;
38
- var e = t[Symbol.toPrimitive];
39
- if (void 0 !== e) {
40
- var i = e.call(t, r || "default");
41
- if ("object" != typeof i) return i;
42
- throw new TypeError("@@toPrimitive must return a primitive value.");
43
- }
44
- return ("string" === r ? String : Number)(t);
45
- }
46
- function _toPropertyKey(t) {
47
- var i = _toPrimitive(t, "string");
48
- return "symbol" == typeof i ? i : i + "";
49
- }
50
-
51
8
  class ArgumentError extends Error {
52
9
  constructor(message) {
53
10
  super(message);
@@ -57,7 +14,6 @@ class ArgumentError extends Error {
57
14
  class MalformedFileError extends Error {
58
15
  constructor(expectedFileType) {
59
16
  super(`Malformed file detected. Make sure the file is a valid ${expectedFileType} file.`);
60
- _defineProperty(this, "expectedFileType", void 0);
61
17
  this.expectedFileType = expectedFileType;
62
18
  }
63
19
  }
@@ -65,7 +21,6 @@ class MalformedFileError extends Error {
65
21
  class MaxXmlDepthError extends Error {
66
22
  constructor(maxDepth) {
67
23
  super(`XML maximum depth reached (max depth: ${maxDepth}).`);
68
- _defineProperty(this, "maxDepth", void 0);
69
24
  this.maxDepth = maxDepth;
70
25
  }
71
26
  }
@@ -73,7 +28,6 @@ class MaxXmlDepthError extends Error {
73
28
  class MissingArgumentError extends ArgumentError {
74
29
  constructor(argName) {
75
30
  super(`Argument '${argName}' is missing.`);
76
- _defineProperty(this, "argName", void 0);
77
31
  this.argName = argName;
78
32
  }
79
33
  }
@@ -81,7 +35,6 @@ class MissingArgumentError extends ArgumentError {
81
35
  class MissingCloseDelimiterError extends Error {
82
36
  constructor(openDelimiterText) {
83
37
  super(`Close delimiter is missing from '${openDelimiterText}'.`);
84
- _defineProperty(this, "openDelimiterText", void 0);
85
38
  this.openDelimiterText = openDelimiterText;
86
39
  }
87
40
  }
@@ -89,7 +42,6 @@ class MissingCloseDelimiterError extends Error {
89
42
  class MissingStartDelimiterError extends Error {
90
43
  constructor(closeDelimiterText) {
91
44
  super(`Open delimiter is missing from '${closeDelimiterText}'.`);
92
- _defineProperty(this, "closeDelimiterText", void 0);
93
45
  this.closeDelimiterText = closeDelimiterText;
94
46
  }
95
47
  }
@@ -97,8 +49,6 @@ class MissingStartDelimiterError extends Error {
97
49
  class TagOptionsParseError extends Error {
98
50
  constructor(tagRawText, parseError) {
99
51
  super(`Failed to parse tag options of '${tagRawText}': ${parseError.message}.`);
100
- _defineProperty(this, "tagRawText", void 0);
101
- _defineProperty(this, "parseError", void 0);
102
52
  this.tagRawText = tagRawText;
103
53
  this.parseError = parseError;
104
54
  }
@@ -107,7 +57,6 @@ class TagOptionsParseError extends Error {
107
57
  class UnclosedTagError extends Error {
108
58
  constructor(tagName) {
109
59
  super(`Tag '${tagName}' is never closed.`);
110
- _defineProperty(this, "tagName", void 0);
111
60
  this.tagName = tagName;
112
61
  }
113
62
  }
@@ -121,9 +70,6 @@ class UnidentifiedFileTypeError extends Error {
121
70
  class UnknownContentTypeError extends Error {
122
71
  constructor(contentType, tagRawText, path) {
123
72
  super(`Content type '${contentType}' does not have a registered plugin to handle it.`);
124
- _defineProperty(this, "tagRawText", void 0);
125
- _defineProperty(this, "contentType", void 0);
126
- _defineProperty(this, "path", void 0);
127
73
  this.contentType = contentType;
128
74
  this.tagRawText = tagRawText;
129
75
  this.path = path;
@@ -133,7 +79,6 @@ class UnknownContentTypeError extends Error {
133
79
  class UnopenedTagError extends Error {
134
80
  constructor(tagName) {
135
81
  super(`Tag '${tagName}' is closed but was never opened.`);
136
- _defineProperty(this, "tagName", void 0);
137
82
  this.tagName = tagName;
138
83
  }
139
84
  }
@@ -141,7 +86,6 @@ class UnopenedTagError extends Error {
141
86
  class UnsupportedFileTypeError extends Error {
142
87
  constructor(fileType) {
143
88
  super(`Filetype "${fileType}" is not supported.`);
144
- _defineProperty(this, "fileType", void 0);
145
89
  this.fileType = fileType;
146
90
  }
147
91
  }
@@ -253,7 +197,7 @@ class Path {
253
197
  return path.substring(0, lastSlashIndex);
254
198
  }
255
199
  static combine(...parts) {
256
- return parts.filter(part => part === null || part === void 0 ? void 0 : part.trim()).join('/');
200
+ return parts.filter(part => part?.trim()).join('/');
257
201
  }
258
202
  }
259
203
 
@@ -436,9 +380,9 @@ function normalizeDoubleQuotes(text) {
436
380
  }
437
381
 
438
382
  class XmlDepthTracker {
383
+ depth = 0;
439
384
  constructor(maxDepth) {
440
385
  this.maxDepth = maxDepth;
441
- _defineProperty(this, "depth", 0);
442
386
  }
443
387
  increment() {
444
388
  this.depth++;
@@ -559,8 +503,7 @@ const XmlNode = {
559
503
  }
560
504
  case domNode.COMMENT_NODE:
561
505
  {
562
- var _domNode$textContent;
563
- xmlNode = this.createCommentNode((_domNode$textContent = domNode.textContent) === null || _domNode$textContent === void 0 ? void 0 : _domNode$textContent.trim());
506
+ xmlNode = this.createCommentNode(domNode.textContent?.trim());
564
507
  break;
565
508
  }
566
509
  case domNode.ELEMENT_NODE:
@@ -946,6 +889,13 @@ function recursiveRemoveEmptyTextNodes(node) {
946
889
  }
947
890
 
948
891
  class XmlParser {
892
+ static xmlHeader = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
893
+ /**
894
+ * We always use the DOMParser from 'xmldom', even in the browser since it
895
+ * handles xml namespaces more forgivingly (required mainly by the
896
+ * RawXmlPlugin).
897
+ */
898
+ static parser = new xmldom.DOMParser();
949
899
  parse(str) {
950
900
  const doc = this.domParse(str);
951
901
  return XmlNode.fromDomNode(doc.documentElement);
@@ -958,20 +908,28 @@ class XmlParser {
958
908
  return XmlParser.xmlHeader + XmlNode.serialize(xmlNode);
959
909
  }
960
910
  }
961
- _defineProperty(XmlParser, "xmlHeader", '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
962
- /**
963
- * We always use the DOMParser from 'xmldom', even in the browser since it
964
- * handles xml namespaces more forgivingly (required mainly by the
965
- * RawXmlPlugin).
966
- */
967
- _defineProperty(XmlParser, "parser", new xmldom.DOMParser());
968
911
 
969
912
  class MatchState {
970
- constructor() {
971
- _defineProperty(this, "delimiterIndex", 0);
972
- _defineProperty(this, "openNodes", []);
973
- _defineProperty(this, "firstMatchIndex", -1);
974
- }
913
+ /**
914
+ * The index of the current delimiter character being matched.
915
+ *
916
+ * Example: If the delimiter is `{!` and delimiterIndex is 0, it means we
917
+ * are now looking for the character `{`. If it is 1, then we are looking
918
+ * for `!`.
919
+ */
920
+ delimiterIndex = 0;
921
+ /**
922
+ * The list of text nodes containing the delimiter characters.
923
+ */
924
+ openNodes = [];
925
+ /**
926
+ * The index of the first character of the delimiter, in the text node it
927
+ * was found at.
928
+ *
929
+ * Example: If the delimiter is `{!`, and the text node content is `abc{!xyz`,
930
+ * then the firstMatchIndex is 3.
931
+ */
932
+ firstMatchIndex = -1;
975
933
  reset() {
976
934
  this.delimiterIndex = 0;
977
935
  this.openNodes = [];
@@ -979,11 +937,11 @@ class MatchState {
979
937
  }
980
938
  }
981
939
  class DelimiterSearcher {
940
+ maxXmlDepth = 20;
941
+ startDelimiter = "{";
942
+ endDelimiter = "}";
982
943
  constructor(docxParser) {
983
944
  this.docxParser = docxParser;
984
- _defineProperty(this, "maxXmlDepth", 20);
985
- _defineProperty(this, "startDelimiter", "{");
986
- _defineProperty(this, "endDelimiter", "}");
987
945
  if (!docxParser) throw new MissingArgumentError("docxParser");
988
946
  }
989
947
  findDelimiters(node) {
@@ -993,8 +951,8 @@ class DelimiterSearcher {
993
951
  // The search efficiency is o(m*n) where n is the text size and m is the
994
952
  // delimiter length. We could use a variation of the KMP algorithm here
995
953
  // to reduce it to o(m+n) but since our m is expected to be small
996
- // (delimiters defaults to 2 characters and even on custom inputs are
997
- // not expected to be much longer) it does not worth the extra
954
+ // (delimiters defaults to a single characters and even on custom inputs
955
+ // are not expected to be much longer) it does not worth the extra
998
956
  // complexity and effort.
999
957
  //
1000
958
 
@@ -1003,44 +961,44 @@ class DelimiterSearcher {
1003
961
  const depth = new XmlDepthTracker(this.maxXmlDepth);
1004
962
  let lookForOpenDelimiter = true;
1005
963
  while (node) {
1006
- // reset state on paragraph transition
964
+ // Reset state on paragraph transition
1007
965
  if (this.docxParser.isParagraphNode(node)) {
1008
966
  match.reset();
1009
967
  }
1010
968
 
1011
- // skip irrelevant nodes
969
+ // Skip irrelevant nodes
1012
970
  if (!this.shouldSearchNode(node)) {
1013
971
  node = this.findNextNode(node, depth);
1014
972
  continue;
1015
973
  }
1016
974
 
1017
- // search delimiters in text nodes
975
+ // Search delimiters in text nodes
1018
976
  match.openNodes.push(node);
1019
977
  let textIndex = 0;
1020
978
  while (textIndex < node.textContent.length) {
1021
979
  const delimiterPattern = lookForOpenDelimiter ? this.startDelimiter : this.endDelimiter;
1022
980
  const char = node.textContent[textIndex];
1023
981
 
1024
- // no match
982
+ // No match
1025
983
  if (char !== delimiterPattern[match.delimiterIndex]) {
1026
984
  [node, textIndex] = this.noMatch(node, textIndex, match);
1027
985
  textIndex++;
1028
986
  continue;
1029
987
  }
1030
988
 
1031
- // first match
989
+ // First match
1032
990
  if (match.firstMatchIndex === -1) {
1033
991
  match.firstMatchIndex = textIndex;
1034
992
  }
1035
993
 
1036
- // partial match
994
+ // Partial match
1037
995
  if (match.delimiterIndex !== delimiterPattern.length - 1) {
1038
996
  match.delimiterIndex++;
1039
997
  textIndex++;
1040
998
  continue;
1041
999
  }
1042
1000
 
1043
- // full delimiter match
1001
+ // Full delimiter match
1044
1002
  [node, textIndex, lookForOpenDelimiter] = this.fullMatch(node, textIndex, lookForOpenDelimiter, match, delimiters);
1045
1003
  textIndex++;
1046
1004
  }
@@ -1050,7 +1008,7 @@ class DelimiterSearcher {
1050
1008
  }
1051
1009
  noMatch(node, textIndex, match) {
1052
1010
  //
1053
- // go back to first open node
1011
+ // Go back to first open node
1054
1012
  //
1055
1013
  // Required for cases where the text has repeating
1056
1014
  // characters that are the same as a delimiter prefix.
@@ -1062,7 +1020,7 @@ class DelimiterSearcher {
1062
1020
  textIndex = match.firstMatchIndex;
1063
1021
  }
1064
1022
 
1065
- // update state
1023
+ // Update state
1066
1024
  match.reset();
1067
1025
  if (textIndex < node.textContent.length - 1) {
1068
1026
  match.openNodes.push(node);
@@ -1070,7 +1028,7 @@ class DelimiterSearcher {
1070
1028
  return [node, textIndex];
1071
1029
  }
1072
1030
  fullMatch(node, textIndex, lookForOpenDelimiter, match, delimiters) {
1073
- // move all delimiters characters to the same text node
1031
+ // Move all delimiters characters to the same text node
1074
1032
  if (match.openNodes.length > 1) {
1075
1033
  const firstNode = first(match.openNodes);
1076
1034
  const lastNode = last(match.openNodes);
@@ -1079,11 +1037,11 @@ class DelimiterSearcher {
1079
1037
  node = firstNode;
1080
1038
  }
1081
1039
 
1082
- // store delimiter
1040
+ // Store delimiter
1083
1041
  const delimiterMark = this.createDelimiterMark(match, lookForOpenDelimiter);
1084
1042
  delimiters.push(delimiterMark);
1085
1043
 
1086
- // update state
1044
+ // Update state
1087
1045
  lookForOpenDelimiter = !lookForOpenDelimiter;
1088
1046
  match.reset();
1089
1047
  if (textIndex < node.textContent.length - 1) {
@@ -1099,23 +1057,23 @@ class DelimiterSearcher {
1099
1057
  return true;
1100
1058
  }
1101
1059
  findNextNode(node, depth) {
1102
- // children
1060
+ // Children
1103
1061
  if (node.childNodes && node.childNodes.length) {
1104
1062
  depth.increment();
1105
1063
  return node.childNodes[0];
1106
1064
  }
1107
1065
 
1108
- // siblings
1066
+ // Siblings
1109
1067
  if (node.nextSibling) return node.nextSibling;
1110
1068
 
1111
- // parent sibling
1069
+ // Parent sibling
1112
1070
  while (node.parentNode) {
1113
1071
  if (node.parentNode.nextSibling) {
1114
1072
  depth.decrement();
1115
1073
  return node.parentNode.nextSibling;
1116
1074
  }
1117
1075
 
1118
- // go up
1076
+ // Go up
1119
1077
  depth.decrement();
1120
1078
  node = node.parentNode;
1121
1079
  }
@@ -1141,11 +1099,9 @@ class ScopeData {
1141
1099
  }
1142
1100
  return result;
1143
1101
  }
1102
+ path = [];
1103
+ strPath = [];
1144
1104
  constructor(data) {
1145
- _defineProperty(this, "scopeDataResolver", void 0);
1146
- _defineProperty(this, "allData", void 0);
1147
- _defineProperty(this, "path", []);
1148
- _defineProperty(this, "strPath", []);
1149
1105
  this.allData = data;
1150
1106
  }
1151
1107
  pathPush(pathPart) {
@@ -1184,7 +1140,6 @@ class TagParser {
1184
1140
  constructor(docParser, delimiters) {
1185
1141
  this.docParser = docParser;
1186
1142
  this.delimiters = delimiters;
1187
- _defineProperty(this, "tagRegex", void 0);
1188
1143
  if (!docParser) throw new MissingArgumentError("docParser");
1189
1144
  if (!delimiters) throw new MissingArgumentError("delimiters");
1190
1145
  const tagOptionsRegex = `${Regex.escape(delimiters.tagOptionsStart)}(?<tagOptions>.*?)${Regex.escape(delimiters.tagOptionsEnd)}`;
@@ -1287,22 +1242,21 @@ class TagParser {
1287
1242
  closeDelimiter.xmlTextNode = endTextNode;
1288
1243
  }
1289
1244
  processTag(tag) {
1290
- var _tagParts$groups, _tagParts$groups2;
1291
1245
  tag.rawText = tag.xmlTextNode.textContent;
1292
1246
  const tagParts = this.tagRegex.exec(tag.rawText);
1293
- const tagName = (((_tagParts$groups = tagParts.groups) === null || _tagParts$groups === void 0 ? void 0 : _tagParts$groups["tagName"]) || '').trim();
1247
+ const tagName = (tagParts.groups?.["tagName"] || '').trim();
1294
1248
 
1295
1249
  // Ignoring empty tags.
1296
- if (!(tagName !== null && tagName !== void 0 && tagName.length)) {
1250
+ if (!tagName?.length) {
1297
1251
  tag.disposition = TagDisposition.SelfClosed;
1298
1252
  return;
1299
1253
  }
1300
1254
 
1301
1255
  // Tag options.
1302
- const tagOptionsText = (((_tagParts$groups2 = tagParts.groups) === null || _tagParts$groups2 === void 0 ? void 0 : _tagParts$groups2["tagOptions"]) || '').trim();
1256
+ const tagOptionsText = (tagParts.groups?.["tagOptions"] || '').trim();
1303
1257
  if (tagOptionsText) {
1304
1258
  try {
1305
- tag.options = JSON5__namespace.parse("{" + normalizeDoubleQuotes(tagOptionsText) + "}");
1259
+ tag.options = JSON5.parse("{" + normalizeDoubleQuotes(tagOptionsText) + "}");
1306
1260
  } catch (e) {
1307
1261
  throw new TagOptionsParseError(tag.rawText, e);
1308
1262
  }
@@ -1368,13 +1322,10 @@ class MimeTypeHelper {
1368
1322
  }
1369
1323
 
1370
1324
  class TemplatePlugin {
1371
- constructor() {
1372
- /**
1373
- * The content type this plugin handles.
1374
- */
1375
- _defineProperty(this, "contentType", void 0);
1376
- _defineProperty(this, "utilities", void 0);
1377
- }
1325
+ /**
1326
+ * The content type this plugin handles.
1327
+ */
1328
+
1378
1329
  /**
1379
1330
  * Called by the TemplateHandler at runtime.
1380
1331
  */
@@ -1415,10 +1366,7 @@ class TemplatePlugin {
1415
1366
  */
1416
1367
  let nextImageId = 1;
1417
1368
  class ImagePlugin extends TemplatePlugin {
1418
- constructor(...args) {
1419
- super(...args);
1420
- _defineProperty(this, "contentType", 'image');
1421
- }
1369
+ contentType = 'image';
1422
1370
  async simpleTagReplacements(tag, data, context) {
1423
1371
  const wordTextNode = this.utilities.docxParser.containingTextNode(tag.xmlTextNode);
1424
1372
  const content = data.getScopeData();
@@ -1570,12 +1518,11 @@ let ContentPartType = /*#__PURE__*/function (ContentPartType) {
1570
1518
  * http://officeopenxml.com/anatomyofOOXML.php
1571
1519
  */
1572
1520
  class ContentTypesFile {
1521
+ static contentTypesFilePath = '[Content_Types].xml';
1522
+ addedNew = false;
1573
1523
  constructor(zip, xmlParser) {
1574
1524
  this.zip = zip;
1575
1525
  this.xmlParser = xmlParser;
1576
- _defineProperty(this, "addedNew", false);
1577
- _defineProperty(this, "root", void 0);
1578
- _defineProperty(this, "contentTypes", void 0);
1579
1526
  }
1580
1527
  async ensureContentType(mime) {
1581
1528
  // parse the content types file
@@ -1630,17 +1577,16 @@ class ContentTypesFile {
1630
1577
  }
1631
1578
  }
1632
1579
  }
1633
- _defineProperty(ContentTypesFile, "contentTypesFilePath", '[Content_Types].xml');
1634
1580
 
1635
1581
  /**
1636
1582
  * Handles media files of the main document.
1637
1583
  */
1638
1584
  class MediaFiles {
1585
+ static mediaDir = 'word/media';
1586
+ files = new Map();
1587
+ nextFileId = 0;
1639
1588
  constructor(zip) {
1640
1589
  this.zip = zip;
1641
- _defineProperty(this, "hashes", void 0);
1642
- _defineProperty(this, "files", new Map());
1643
- _defineProperty(this, "nextFileId", 0);
1644
1590
  }
1645
1591
 
1646
1592
  /**
@@ -1699,23 +1645,17 @@ class MediaFiles {
1699
1645
  }
1700
1646
  }
1701
1647
  }
1702
- _defineProperty(MediaFiles, "mediaDir", 'word/media');
1703
1648
 
1704
1649
  class Relationship {
1705
1650
  static fromXml(xml) {
1706
- var _xml$attributes, _xml$attributes2, _xml$attributes3, _xml$attributes4;
1707
1651
  return new Relationship({
1708
- id: (_xml$attributes = xml.attributes) === null || _xml$attributes === void 0 ? void 0 : _xml$attributes['Id'],
1709
- type: (_xml$attributes2 = xml.attributes) === null || _xml$attributes2 === void 0 ? void 0 : _xml$attributes2['Type'],
1710
- target: (_xml$attributes3 = xml.attributes) === null || _xml$attributes3 === void 0 ? void 0 : _xml$attributes3['Target'],
1711
- targetMode: (_xml$attributes4 = xml.attributes) === null || _xml$attributes4 === void 0 ? void 0 : _xml$attributes4['TargetMode']
1652
+ id: xml.attributes?.['Id'],
1653
+ type: xml.attributes?.['Type'],
1654
+ target: xml.attributes?.['Target'],
1655
+ targetMode: xml.attributes?.['TargetMode']
1712
1656
  });
1713
1657
  }
1714
1658
  constructor(initial) {
1715
- _defineProperty(this, "id", void 0);
1716
- _defineProperty(this, "type", void 0);
1717
- _defineProperty(this, "target", void 0);
1718
- _defineProperty(this, "targetMode", void 0);
1719
1659
  Object.assign(this, initial);
1720
1660
  }
1721
1661
  toXml() {
@@ -1739,17 +1679,13 @@ class Relationship {
1739
1679
  * http://officeopenxml.com/anatomyofOOXML.php
1740
1680
  */
1741
1681
  class Rels {
1682
+ nextRelId = 0;
1742
1683
  constructor(partPath, zip, xmlParser) {
1743
1684
  this.zip = zip;
1744
1685
  this.xmlParser = xmlParser;
1745
- _defineProperty(this, "rels", void 0);
1746
- _defineProperty(this, "relTargets", void 0);
1747
- _defineProperty(this, "nextRelId", 0);
1748
- _defineProperty(this, "partDir", void 0);
1749
- _defineProperty(this, "relsFilePath", void 0);
1750
1686
  this.partDir = partPath && Path.getDirectory(partPath);
1751
1687
  const partFilename = partPath && Path.getFilename(partPath);
1752
- this.relsFilePath = Path.combine(this.partDir, '_rels', `${partFilename !== null && partFilename !== void 0 ? partFilename : ''}.rels`);
1688
+ this.relsFilePath = Path.combine(this.partDir, '_rels', `${partFilename ?? ''}.rels`);
1753
1689
  }
1754
1690
 
1755
1691
  /**
@@ -1878,8 +1814,6 @@ class XmlPart {
1878
1814
  this.path = path;
1879
1815
  this.zip = zip;
1880
1816
  this.xmlParser = xmlParser;
1881
- _defineProperty(this, "rels", void 0);
1882
- _defineProperty(this, "root", void 0);
1883
1817
  this.rels = new Rels(this.path, zip, xmlParser);
1884
1818
  }
1885
1819
 
@@ -1927,6 +1861,8 @@ class XmlPart {
1927
1861
  * Represents a single docx file.
1928
1862
  */
1929
1863
  class Docx {
1864
+ static mainDocumentRelType = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument';
1865
+
1930
1866
  //
1931
1867
  // static methods
1932
1868
  //
@@ -1937,17 +1873,18 @@ class Docx {
1937
1873
  return new Docx(mainDocumentPath, zip, xmlParser);
1938
1874
  }
1939
1875
  static async getMainDocumentPath(zip, xmlParser) {
1940
- var _relations$find;
1941
1876
  const rootPart = '';
1942
1877
  const rootRels = new Rels(rootPart, zip, xmlParser);
1943
1878
  const relations = await rootRels.list();
1944
- return (_relations$find = relations.find(rel => rel.type == Docx.mainDocumentRelType)) === null || _relations$find === void 0 ? void 0 : _relations$find.target;
1879
+ return relations.find(rel => rel.type == Docx.mainDocumentRelType)?.target;
1945
1880
  }
1946
1881
 
1947
1882
  //
1948
1883
  // fields
1949
1884
  //
1950
1885
 
1886
+ _parts = {};
1887
+
1951
1888
  /**
1952
1889
  * **Notice:** You should only use this property if there is no other way to
1953
1890
  * do what you need. Use with caution.
@@ -1963,10 +1900,6 @@ class Docx {
1963
1900
  constructor(mainDocumentPath, zip, xmlParser) {
1964
1901
  this.zip = zip;
1965
1902
  this.xmlParser = xmlParser;
1966
- _defineProperty(this, "mainDocument", void 0);
1967
- _defineProperty(this, "mediaFiles", void 0);
1968
- _defineProperty(this, "contentTypes", void 0);
1969
- _defineProperty(this, "_parts", {});
1970
1903
  this.mainDocument = new XmlPart(mainDocumentPath, zip, xmlParser);
1971
1904
  this.mediaFiles = new MediaFiles(zip);
1972
1905
  this.contentTypes = new ContentTypesFile(zip, xmlParser);
@@ -2003,7 +1936,6 @@ class Docx {
2003
1936
  //
2004
1937
 
2005
1938
  async getHeaderOrFooter(type) {
2006
- var _sectionProps$childNo, _attributes;
2007
1939
  const nodeName = this.headerFooterNodeName(type);
2008
1940
  const nodeTypeAttribute = this.headerFooterType(type);
2009
1941
 
@@ -2016,11 +1948,10 @@ class Docx {
2016
1948
  if (sectionProps.nodeName != 'w:sectPr') return null;
2017
1949
 
2018
1950
  // find the header or footer reference
2019
- const reference = (_sectionProps$childNo = sectionProps.childNodes) === null || _sectionProps$childNo === void 0 ? void 0 : _sectionProps$childNo.find(node => {
2020
- var _node$attributes;
2021
- return node.nodeType === XmlNodeType.General && node.nodeName === nodeName && ((_node$attributes = node.attributes) === null || _node$attributes === void 0 ? void 0 : _node$attributes['w:type']) === nodeTypeAttribute;
1951
+ const reference = sectionProps.childNodes?.find(node => {
1952
+ return node.nodeType === XmlNodeType.General && node.nodeName === nodeName && node.attributes?.['w:type'] === nodeTypeAttribute;
2022
1953
  });
2023
- const relId = reference === null || reference === void 0 ? void 0 : (_attributes = reference.attributes) === null || _attributes === void 0 ? void 0 : _attributes['r:id'];
1954
+ const relId = reference?.attributes?.['r:id'];
2024
1955
  if (!relId) return null;
2025
1956
 
2026
1957
  // return the XmlPart
@@ -2071,9 +2002,38 @@ class Docx {
2071
2002
  await this.contentTypes.save();
2072
2003
  }
2073
2004
  }
2074
- _defineProperty(Docx, "mainDocumentRelType", 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument');
2075
2005
 
2076
2006
  class DocxParser {
2007
+ /*
2008
+ * Word markup intro:
2009
+ *
2010
+ * In Word text nodes are contained in "run" nodes (which specifies text
2011
+ * properties such as font and color). The "run" nodes in turn are
2012
+ * contained in paragraph nodes which is the core unit of content.
2013
+ *
2014
+ * Example:
2015
+ *
2016
+ * <w:p> <-- paragraph
2017
+ * <w:r> <-- run
2018
+ * <w:rPr> <-- run properties
2019
+ * <w:b/> <-- bold
2020
+ * </w:rPr>
2021
+ * <w:t>This is text.</w:t> <-- actual text
2022
+ * </w:r>
2023
+ * </w:p>
2024
+ *
2025
+ * see: http://officeopenxml.com/WPcontentOverview.php
2026
+ */
2027
+
2028
+ static PARAGRAPH_NODE = 'w:p';
2029
+ static PARAGRAPH_PROPERTIES_NODE = 'w:pPr';
2030
+ static RUN_NODE = 'w:r';
2031
+ static RUN_PROPERTIES_NODE = 'w:rPr';
2032
+ static TEXT_NODE = 'w:t';
2033
+ static TABLE_ROW_NODE = 'w:tr';
2034
+ static TABLE_CELL_NODE = 'w:tc';
2035
+ static NUMBER_PROPERTIES_NODE = 'w:numPr';
2036
+
2077
2037
  //
2078
2038
  // constructor
2079
2039
  //
@@ -2372,9 +2332,8 @@ class DocxParser {
2372
2332
  //
2373
2333
 
2374
2334
  isEmptyTextNode(node) {
2375
- var _node$childNodes;
2376
2335
  if (!this.isTextNode(node)) throw new Error(`Text node expected but '${node.nodeName}' received.`);
2377
- if (!((_node$childNodes = node.childNodes) !== null && _node$childNodes !== void 0 && _node$childNodes.length)) return true;
2336
+ if (!node.childNodes?.length) return true;
2378
2337
  const xmlTextNode = node.childNodes[0];
2379
2338
  if (!XmlNode.isTextNode(xmlTextNode)) throw new Error("Invalid XML structure. 'w:t' node should contain a single text node only.");
2380
2339
  if (!xmlTextNode.textContent) return true;
@@ -2382,8 +2341,7 @@ class DocxParser {
2382
2341
  }
2383
2342
  isEmptyRun(node) {
2384
2343
  if (!this.isRunNode(node)) throw new Error(`Run node expected but '${node.nodeName}' received.`);
2385
- for (const child of (_node$childNodes2 = node.childNodes) !== null && _node$childNodes2 !== void 0 ? _node$childNodes2 : []) {
2386
- var _node$childNodes2;
2344
+ for (const child of node.childNodes ?? []) {
2387
2345
  if (this.isRunPropertiesNode(child)) continue;
2388
2346
  if (this.isTextNode(child) && this.isEmptyTextNode(child)) continue;
2389
2347
  return false;
@@ -2391,40 +2349,10 @@ class DocxParser {
2391
2349
  return true;
2392
2350
  }
2393
2351
  }
2394
- /*
2395
- * Word markup intro:
2396
- *
2397
- * In Word text nodes are contained in "run" nodes (which specifies text
2398
- * properties such as font and color). The "run" nodes in turn are
2399
- * contained in paragraph nodes which is the core unit of content.
2400
- *
2401
- * Example:
2402
- *
2403
- * <w:p> <-- paragraph
2404
- * <w:r> <-- run
2405
- * <w:rPr> <-- run properties
2406
- * <w:b/> <-- bold
2407
- * </w:rPr>
2408
- * <w:t>This is text.</w:t> <-- actual text
2409
- * </w:r>
2410
- * </w:p>
2411
- *
2412
- * see: http://officeopenxml.com/WPcontentOverview.php
2413
- */
2414
- _defineProperty(DocxParser, "PARAGRAPH_NODE", 'w:p');
2415
- _defineProperty(DocxParser, "PARAGRAPH_PROPERTIES_NODE", 'w:pPr');
2416
- _defineProperty(DocxParser, "RUN_NODE", 'w:r');
2417
- _defineProperty(DocxParser, "RUN_PROPERTIES_NODE", 'w:rPr');
2418
- _defineProperty(DocxParser, "TEXT_NODE", 'w:t');
2419
- _defineProperty(DocxParser, "TABLE_ROW_NODE", 'w:tr');
2420
- _defineProperty(DocxParser, "TABLE_CELL_NODE", 'w:tc');
2421
- _defineProperty(DocxParser, "NUMBER_PROPERTIES_NODE", 'w:numPr');
2422
2352
 
2423
2353
  class LinkPlugin extends TemplatePlugin {
2424
- constructor(...args) {
2425
- super(...args);
2426
- _defineProperty(this, "contentType", 'link');
2427
- }
2354
+ static linkRelType = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink';
2355
+ contentType = 'link';
2428
2356
  async simpleTagReplacements(tag, data, context) {
2429
2357
  const wordTextNode = this.utilities.docxParser.containingTextNode(tag.xmlTextNode);
2430
2358
  const content = data.getScopeData();
@@ -2493,12 +2421,8 @@ class LinkPlugin extends TemplatePlugin {
2493
2421
  }
2494
2422
  }
2495
2423
  }
2496
- _defineProperty(LinkPlugin, "linkRelType", 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink');
2497
2424
 
2498
2425
  class LoopListStrategy {
2499
- constructor() {
2500
- _defineProperty(this, "utilities", void 0);
2501
- }
2502
2426
  setUtilities(utilities) {
2503
2427
  this.utilities = utilities;
2504
2428
  }
@@ -2536,9 +2460,6 @@ class LoopListStrategy {
2536
2460
  }
2537
2461
 
2538
2462
  class LoopParagraphStrategy {
2539
- constructor() {
2540
- _defineProperty(this, "utilities", void 0);
2541
- }
2542
2463
  setUtilities(utilities) {
2543
2464
  this.utilities = utilities;
2544
2465
  }
@@ -2609,9 +2530,6 @@ let LoopOver = /*#__PURE__*/function (LoopOver) {
2609
2530
  }({});
2610
2531
 
2611
2532
  class LoopTableStrategy {
2612
- constructor() {
2613
- _defineProperty(this, "utilities", void 0);
2614
- }
2615
2533
  setUtilities(utilities) {
2616
2534
  this.utilities = utilities;
2617
2535
  }
@@ -2623,7 +2541,7 @@ class LoopTableStrategy {
2623
2541
  if (!closeParagraph.parentNode) return false;
2624
2542
  if (!this.utilities.docxParser.isTableCellNode(closeParagraph.parentNode)) return false;
2625
2543
  const options = openTag.options;
2626
- const forceRowLoop = (options === null || options === void 0 ? void 0 : options.loopOver) === LoopOver.Row;
2544
+ const forceRowLoop = options?.loopOver === LoopOver.Row;
2627
2545
 
2628
2546
  // If both tags are in the same cell, assume it's a paragraph loop (iterate content, not rows).
2629
2547
  if (!forceRowLoop && openParagraph.parentNode === closeParagraph.parentNode) return false;
@@ -2660,12 +2578,9 @@ class LoopTableStrategy {
2660
2578
 
2661
2579
  const LOOP_CONTENT_TYPE = 'loop';
2662
2580
  class LoopPlugin extends TemplatePlugin {
2663
- constructor(...args) {
2664
- super(...args);
2665
- _defineProperty(this, "contentType", LOOP_CONTENT_TYPE);
2666
- _defineProperty(this, "loopStrategies", [new LoopTableStrategy(), new LoopListStrategy(), new LoopParagraphStrategy() // the default strategy
2667
- ]);
2668
- }
2581
+ contentType = LOOP_CONTENT_TYPE;
2582
+ loopStrategies = [new LoopTableStrategy(), new LoopListStrategy(), new LoopParagraphStrategy() // the default strategy
2583
+ ];
2669
2584
  setUtilities(utilities) {
2670
2585
  this.utilities = utilities;
2671
2586
  this.loopStrategies.forEach(strategy => strategy.setUtilities(utilities));
@@ -2770,14 +2685,11 @@ class LoopPlugin extends TemplatePlugin {
2770
2685
  }
2771
2686
 
2772
2687
  class RawXmlPlugin extends TemplatePlugin {
2773
- constructor(...args) {
2774
- super(...args);
2775
- _defineProperty(this, "contentType", 'rawXml');
2776
- }
2688
+ contentType = 'rawXml';
2777
2689
  simpleTagReplacements(tag, data) {
2778
2690
  const value = data.getScopeData();
2779
- const replaceNode = value !== null && value !== void 0 && value.replaceParagraph ? this.utilities.docxParser.containingParagraphNode(tag.xmlTextNode) : this.utilities.docxParser.containingTextNode(tag.xmlTextNode);
2780
- if (typeof (value === null || value === void 0 ? void 0 : value.xml) === 'string') {
2691
+ const replaceNode = value?.replaceParagraph ? this.utilities.docxParser.containingParagraphNode(tag.xmlTextNode) : this.utilities.docxParser.containingTextNode(tag.xmlTextNode);
2692
+ if (typeof value?.xml === 'string') {
2781
2693
  const newNode = this.utilities.xmlParser.parse(value.xml);
2782
2694
  XmlNode.insertBefore(newNode, replaceNode);
2783
2695
  }
@@ -2787,10 +2699,8 @@ class RawXmlPlugin extends TemplatePlugin {
2787
2699
 
2788
2700
  const TEXT_CONTENT_TYPE = 'text';
2789
2701
  class TextPlugin extends TemplatePlugin {
2790
- constructor(...args) {
2791
- super(...args);
2792
- _defineProperty(this, "contentType", TEXT_CONTENT_TYPE);
2793
- }
2702
+ contentType = TEXT_CONTENT_TYPE;
2703
+
2794
2704
  /**
2795
2705
  * Replace the node text content with the specified value.
2796
2706
  */
@@ -2865,7 +2775,6 @@ class TemplateCompiler {
2865
2775
  this.delimiterSearcher = delimiterSearcher;
2866
2776
  this.tagParser = tagParser;
2867
2777
  this.options = options;
2868
- _defineProperty(this, "pluginsLookup", void 0);
2869
2778
  this.pluginsLookup = toDictionary(plugins, p => p.contentType);
2870
2779
  }
2871
2780
 
@@ -2964,9 +2873,6 @@ class TemplateCompiler {
2964
2873
  }
2965
2874
 
2966
2875
  class TemplateExtension {
2967
- constructor() {
2968
- _defineProperty(this, "utilities", void 0);
2969
- }
2970
2876
  /**
2971
2877
  * Called by the TemplateHandler at runtime.
2972
2878
  */
@@ -3018,7 +2924,7 @@ class ZipObject {
3018
2924
 
3019
2925
  class Zip {
3020
2926
  static async load(file) {
3021
- const zip = await JSZip__namespace.loadAsync(file);
2927
+ const zip = await JSZip.loadAsync(file);
3022
2928
  return new Zip(zip);
3023
2929
  }
3024
2930
  constructor(zip) {
@@ -3052,13 +2958,13 @@ class Zip {
3052
2958
  }
3053
2959
 
3054
2960
  class Delimiters {
2961
+ tagStart = "{";
2962
+ tagEnd = "}";
2963
+ containerTagOpen = "#";
2964
+ containerTagClose = "/";
2965
+ tagOptionsStart = "[";
2966
+ tagOptionsEnd = "]";
3055
2967
  constructor(initial) {
3056
- _defineProperty(this, "tagStart", "{");
3057
- _defineProperty(this, "tagEnd", "}");
3058
- _defineProperty(this, "containerTagOpen", "#");
3059
- _defineProperty(this, "containerTagClose", "/");
3060
- _defineProperty(this, "tagOptionsStart", "[");
3061
- _defineProperty(this, "tagOptionsEnd", "]");
3062
2968
  Object.assign(this, initial);
3063
2969
  this.encodeAndValidate();
3064
2970
  if (this.containerTagOpen === this.containerTagClose) throw new Error(`${"containerTagOpen"} can not be equal to ${"containerTagClose"}`);
@@ -3074,22 +2980,22 @@ class Delimiters {
3074
2980
  }
3075
2981
 
3076
2982
  class TemplateHandlerOptions {
2983
+ plugins = createDefaultPlugins();
2984
+
2985
+ /**
2986
+ * Determines the behavior in case of an empty input data. If set to true
2987
+ * the tag will be left untouched, if set to false the tag will be replaced
2988
+ * by an empty string.
2989
+ *
2990
+ * Default: false
2991
+ */
2992
+ skipEmptyTags = false;
2993
+ defaultContentType = TEXT_CONTENT_TYPE;
2994
+ containerContentType = LOOP_CONTENT_TYPE;
2995
+ delimiters = new Delimiters();
2996
+ maxXmlDepth = 20;
2997
+ extensions = {};
3077
2998
  constructor(initial) {
3078
- _defineProperty(this, "plugins", createDefaultPlugins());
3079
- /**
3080
- * Determines the behavior in case of an empty input data. If set to true
3081
- * the tag will be left untouched, if set to false the tag will be replaced
3082
- * by an empty string.
3083
- *
3084
- * Default: false
3085
- */
3086
- _defineProperty(this, "skipEmptyTags", false);
3087
- _defineProperty(this, "defaultContentType", TEXT_CONTENT_TYPE);
3088
- _defineProperty(this, "containerContentType", LOOP_CONTENT_TYPE);
3089
- _defineProperty(this, "delimiters", new Delimiters());
3090
- _defineProperty(this, "maxXmlDepth", 20);
3091
- _defineProperty(this, "extensions", {});
3092
- _defineProperty(this, "scopeDataResolver", void 0);
3093
2999
  Object.assign(this, initial);
3094
3000
  if (initial) {
3095
3001
  this.delimiters = new Delimiters(initial.delimiters);
@@ -3101,16 +3007,12 @@ class TemplateHandlerOptions {
3101
3007
  }
3102
3008
 
3103
3009
  class TemplateHandler {
3010
+ /**
3011
+ * Version number of the `easy-template-x` library.
3012
+ */
3013
+ version = "4.1.2" ;
3014
+ xmlParser = new XmlParser();
3104
3015
  constructor(options) {
3105
- var _this$options$extensi, _this$options$extensi2, _this$options$extensi3, _this$options$extensi4;
3106
- /**
3107
- * Version number of the `easy-template-x` library.
3108
- */
3109
- _defineProperty(this, "version", "4.1.0" );
3110
- _defineProperty(this, "xmlParser", new XmlParser());
3111
- _defineProperty(this, "docxParser", void 0);
3112
- _defineProperty(this, "compiler", void 0);
3113
- _defineProperty(this, "options", void 0);
3114
3016
  this.options = new TemplateHandlerOptions(options);
3115
3017
 
3116
3018
  //
@@ -3141,10 +3043,10 @@ class TemplateHandler {
3141
3043
  tagParser,
3142
3044
  compiler: this.compiler
3143
3045
  };
3144
- (_this$options$extensi = this.options.extensions) === null || _this$options$extensi === void 0 ? void 0 : (_this$options$extensi2 = _this$options$extensi.beforeCompilation) === null || _this$options$extensi2 === void 0 ? void 0 : _this$options$extensi2.forEach(extension => {
3046
+ this.options.extensions?.beforeCompilation?.forEach(extension => {
3145
3047
  extension.setUtilities(extensionUtilities);
3146
3048
  });
3147
- (_this$options$extensi3 = this.options.extensions) === null || _this$options$extensi3 === void 0 ? void 0 : (_this$options$extensi4 = _this$options$extensi3.afterCompilation) === null || _this$options$extensi4 === void 0 ? void 0 : _this$options$extensi4.forEach(extension => {
3049
+ this.options.extensions?.afterCompilation?.forEach(extension => {
3148
3050
  extension.setUtilities(extensionUtilities);
3149
3051
  });
3150
3052
  }
@@ -3166,18 +3068,17 @@ class TemplateHandler {
3166
3068
  };
3167
3069
  const contentParts = await docx.getContentParts();
3168
3070
  for (const part of contentParts) {
3169
- var _this$options$extensi5, _this$options$extensi6;
3170
3071
  context.currentPart = part;
3171
3072
 
3172
3073
  // extensions - before compilation
3173
- await this.callExtensions((_this$options$extensi5 = this.options.extensions) === null || _this$options$extensi5 === void 0 ? void 0 : _this$options$extensi5.beforeCompilation, scopeData, context);
3074
+ await this.callExtensions(this.options.extensions?.beforeCompilation, scopeData, context);
3174
3075
 
3175
3076
  // compilation (do replacements)
3176
3077
  const xmlRoot = await part.xmlRoot();
3177
3078
  await this.compiler.compile(xmlRoot, scopeData, context);
3178
3079
 
3179
3080
  // extensions - after compilation
3180
- await this.callExtensions((_this$options$extensi6 = this.options.extensions) === null || _this$options$extensi6 === void 0 ? void 0 : _this$options$extensi6.afterCompilation, scopeData, context);
3081
+ await this.callExtensions(this.options.extensions?.afterCompilation, scopeData, context);
3181
3082
  }
3182
3083
 
3183
3084
  // export the result
@@ -3244,7 +3145,7 @@ class TemplateHandler {
3244
3145
  let zip;
3245
3146
  try {
3246
3147
  zip = await Zip.load(file);
3247
- } catch (_unused) {
3148
+ } catch {
3248
3149
  throw new MalformedFileError('docx');
3249
3150
  }
3250
3151