@microsoft/connected-workbooks 3.2.2-beta → 3.3.2-beta

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.
@@ -2,8 +2,8 @@
2
2
  // Copyright (c) Microsoft Corporation.
3
3
  // Licensed under the MIT license.
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.maxQueryLength = exports.divider = exports.section1PathPrefix = exports.emptyValue = exports.falseValue = exports.trueValue = exports.pivotCachesPathPrefix = exports.xmlTextResultType = exports.textResultType = exports.application = exports.uint8ArrayType = exports.blobFileType = exports.columnIndexOutOfRangeErr = exports.relsNotFoundErr = exports.arrayIsntMxNErr = exports.unexpectedErr = exports.promotedHeadersCannotBeUsedWithoutAdjustingColumnNamesErr = exports.InvalidColumnNameErr = exports.stylesNotFoundErr = exports.EmptyQueryNameErr = exports.QueryNameInvalidCharsErr = exports.QueryNameMaxLengthErr = exports.invalidDataTypeErr = exports.headerNotFoundErr = exports.invalidValueInColumnErr = exports.tableNotFoundErr = exports.queryTableNotFoundErr = exports.templateWithInitialDataErr = exports.formulaSectionNotFoundErr = exports.queryConnectionNotFoundErr = exports.queryAndPivotTableNotFoundErr = exports.queryNameNotFoundErr = exports.emptyQueryMashupErr = exports.base64NotFoundErr = exports.sheetsNotFoundErr = exports.connectionsNotFoundErr = exports.sharedStringsNotFoundErr = exports.docPropsRootElement = exports.docMetadataXmlPath = exports.relsXmlPath = exports.docPropsCoreXmlPath = exports.section1mPath = exports.pivotCachesPath = exports.queryTablesPath = exports.workbookXmlPath = exports.queryTableXmlPath = exports.tableXmlPath = exports.sheetsXmlPath = exports.sharedStringsXmlPath = exports.connectionsXmlPath = void 0;
6
- exports.OFU = exports.headers = exports.URLS = exports.defaults = exports.elementAttributesValues = exports.dataTypeKind = exports.elementAttributes = exports.element = exports.BOM = exports.falseStr = exports.trueStr = void 0;
5
+ exports.textResultType = exports.application = exports.uint8ArrayType = exports.blobFileType = exports.relationshipErr = exports.columnIndexOutOfRangeErr = exports.xlRelsNotFoundErr = exports.relsNotFoundErr = exports.arrayIsntMxNErr = exports.unexpectedErr = exports.promotedHeadersCannotBeUsedWithoutAdjustingColumnNamesErr = exports.InvalidColumnNameErr = exports.stylesNotFoundErr = exports.EmptyQueryNameErr = exports.QueryNameInvalidCharsErr = exports.QueryNameMaxLengthErr = exports.invalidDataTypeErr = exports.headerNotFoundErr = exports.invalidValueInColumnErr = exports.tableReferenceNotFoundErr = exports.tableNotFoundErr = exports.queryTableNotFoundErr = exports.templateWithInitialDataErr = exports.formulaSectionNotFoundErr = exports.queryConnectionNotFoundErr = exports.queryAndPivotTableNotFoundErr = exports.queryNameNotFoundErr = exports.emptyQueryMashupErr = exports.base64NotFoundErr = exports.sheetsNotFoundErr = exports.WorkbookNotFoundERR = exports.connectionsNotFoundErr = exports.sharedStringsNotFoundErr = exports.docPropsAppXmlPath = exports.labelInfoXmlPath = exports.workbookRelsXmlPath = exports.docPropsRootElement = exports.docMetadataXmlPath = exports.relsXmlPath = exports.docPropsCoreXmlPath = exports.section1mPath = exports.pivotCachesPath = exports.tablesFolderPath = exports.queryTablesPath = exports.workbookXmlPath = exports.queryTableXmlPath = exports.tableXmlPath = exports.sheetsXmlPath = exports.sharedStringsXmlPath = exports.connectionsXmlPath = void 0;
6
+ exports.OFU = exports.headers = exports.URLS = exports.defaults = exports.elementAttributesValues = exports.dataTypeKind = exports.elementAttributes = exports.element = exports.BOM = exports.falseStr = exports.trueStr = exports.maxQueryLength = exports.divider = exports.section1PathPrefix = exports.emptyValue = exports.falseValue = exports.trueValue = exports.pivotCachesPathPrefix = exports.xmlTextResultType = void 0;
7
7
  exports.connectionsXmlPath = "xl/connections.xml";
8
8
  exports.sharedStringsXmlPath = "xl/sharedStrings.xml";
9
9
  exports.sheetsXmlPath = "xl/worksheets/sheet1.xml";
@@ -11,14 +11,19 @@ exports.tableXmlPath = "xl/tables/table1.xml";
11
11
  exports.queryTableXmlPath = "xl/queryTables/queryTable1.xml";
12
12
  exports.workbookXmlPath = "xl/workbook.xml";
13
13
  exports.queryTablesPath = "xl/queryTables/";
14
+ exports.tablesFolderPath = "xl/tables/";
14
15
  exports.pivotCachesPath = "xl/pivotCache/";
15
16
  exports.section1mPath = "Formulas/Section1.m";
16
17
  exports.docPropsCoreXmlPath = "docProps/core.xml";
17
18
  exports.relsXmlPath = "_rels/.rels";
18
19
  exports.docMetadataXmlPath = "docMetadata";
19
20
  exports.docPropsRootElement = "cp:coreProperties";
21
+ exports.workbookRelsXmlPath = "xl/_rels/workbook.xml.rels";
22
+ exports.labelInfoXmlPath = "docMetadata/LabelInfo.xml";
23
+ exports.docPropsAppXmlPath = "docProps/app.xml";
20
24
  exports.sharedStringsNotFoundErr = "SharedStrings were not found in template";
21
25
  exports.connectionsNotFoundErr = "Connections were not found in template";
26
+ exports.WorkbookNotFoundERR = "workbook was not found in template";
22
27
  exports.sheetsNotFoundErr = "Sheets were not found in template";
23
28
  exports.base64NotFoundErr = "Base64 was not found in template";
24
29
  exports.emptyQueryMashupErr = "Query mashup is empty";
@@ -29,6 +34,7 @@ exports.formulaSectionNotFoundErr = "Formula section wasn't found in template";
29
34
  exports.templateWithInitialDataErr = "Cannot use a template file with initial data";
30
35
  exports.queryTableNotFoundErr = "Query table wasn't found in template";
31
36
  exports.tableNotFoundErr = "Table wasn't found in template";
37
+ exports.tableReferenceNotFoundErr = "Reference not found in the table XML.";
32
38
  exports.invalidValueInColumnErr = "Invalid cell value in column";
33
39
  exports.headerNotFoundErr = "Invalid JSON file, header is missing";
34
40
  exports.invalidDataTypeErr = "Invalid JSON file, invalid data type";
@@ -41,7 +47,9 @@ exports.promotedHeadersCannotBeUsedWithoutAdjustingColumnNamesErr = "Headers can
41
47
  exports.unexpectedErr = "Unexpected error";
42
48
  exports.arrayIsntMxNErr = "Array isn't MxN";
43
49
  exports.relsNotFoundErr = ".rels were not found in template";
50
+ exports.xlRelsNotFoundErr = "workbook.xml.rels were not found xl";
44
51
  exports.columnIndexOutOfRangeErr = "Column index out of range";
52
+ exports.relationshipErr = "Relationship not found";
45
53
  exports.blobFileType = "blob";
46
54
  exports.uint8ArrayType = "uint8array";
47
55
  exports.application = "application/xlsx";
@@ -85,6 +93,9 @@ exports.element = {
85
93
  dimension: "dimension",
86
94
  selection: "selection",
87
95
  kindCell: "c",
96
+ sheet: "sheet",
97
+ relationships: "Relationships",
98
+ relationship: "Relationship"
88
99
  };
89
100
  exports.elementAttributes = {
90
101
  connection: "connection",
@@ -98,6 +109,11 @@ exports.elementAttributes = {
98
109
  name: "name",
99
110
  description: "description",
100
111
  id: "id",
112
+ Id: "Id",
113
+ relationId: "r:id",
114
+ relationId1: "RId1",
115
+ relationId2: "RId2",
116
+ relationId3: "RId3",
101
117
  type: "Type",
102
118
  value: "Value",
103
119
  relationshipInfo: "RelationshipInfoContainer",
@@ -117,6 +133,7 @@ exports.elementAttributes = {
117
133
  x14acDyDescent: "x14ac:dyDescent",
118
134
  xr3uid: "xr3:uid",
119
135
  space: "xml:space",
136
+ target: "Target",
120
137
  };
121
138
  exports.dataTypeKind = {
122
139
  string: "str",
@@ -134,6 +151,7 @@ exports.defaults = {
134
151
  queryName: "Query1",
135
152
  sheetName: "Sheet1",
136
153
  columnName: "Column",
154
+ tableName: "Table1",
137
155
  };
138
156
  exports.URLS = {
139
157
  PQ: [
@@ -93,13 +93,27 @@ var convertToExcelColumn = function (index) {
93
93
  var base = 26; // number of letters in the alphabet
94
94
  while (index >= 0) {
95
95
  var remainder = index % base;
96
- columnStr = String.fromCharCode(remainder + 65) + columnStr; // ASCII 'A' is 65
96
+ columnStr = String.fromCharCode(remainder + 'A'.charCodeAt(0)) + columnStr;
97
97
  index = Math.floor(index / base) - 1;
98
98
  }
99
99
  return columnStr;
100
100
  };
101
- var getTableReference = function (numberOfCols, numberOfRows) {
102
- return "A1:".concat(getCellReferenceRelative(numberOfCols, numberOfRows));
101
+ /**
102
+ * Parse an Excel range (e.g. "B2:D10") and return its starting row and column indices.
103
+ * @param cellRangeRef - Range reference string.
104
+ * @returns Object with numeric row and column.
105
+ */
106
+ var GetStartPosition = function (cellRangeRef) {
107
+ var match = cellRangeRef.toUpperCase().match(/^([A-Z]+)(\d+)/);
108
+ if (!match) {
109
+ return { row: 0, column: 0 };
110
+ }
111
+ var colLetters = match[1], rowStr = match[2];
112
+ var row = parseInt(rowStr, 10);
113
+ var column = colLetters
114
+ .split("")
115
+ .reduce(function (acc, char) { return acc * 26 + (char.charCodeAt(0) - "A".charCodeAt(0) + 1); }, 0);
116
+ return { row: row, column: column };
103
117
  };
104
118
  var createCellElement = function (doc, colIndex, rowIndex, data) {
105
119
  var cell = doc.createElementNS(doc.documentElement.namespaceURI, constants_1.element.kindCell);
@@ -146,8 +160,8 @@ exports.default = {
146
160
  getCellReferenceRelative: getCellReferenceRelative,
147
161
  getCellReferenceAbsolute: getCellReferenceAbsolute,
148
162
  createCell: createCellElement,
149
- getTableReference: getTableReference,
150
163
  updateCellData: updateCellData,
151
164
  resolveType: resolveType,
152
165
  convertToExcelColumn: convertToExcelColumn,
166
+ GetStartPosition: GetStartPosition,
153
167
  };
@@ -45,7 +45,17 @@ var constants_1 = require("./constants");
45
45
  var documentUtils_1 = __importDefault(require("./documentUtils"));
46
46
  var uuid_1 = require("uuid");
47
47
  var xmldom_qsa_1 = require("xmldom-qsa");
48
- var updateTableInitialDataIfNeeded = function (zip, tableData, updateQueryTable) { return __awaiter(void 0, void 0, void 0, function () {
48
+ /**
49
+ * Update initial data for a table, its sheet, query table, and defined name if provided.
50
+ * @param zip - The JSZip instance containing workbook parts.
51
+ * @param cellRangeRef - Cell range reference (e.g. "A1:C5").
52
+ * @param sheetPath - Path to the sheet XML within the zip.
53
+ * @param tablePath - Path to the table XML within the zip.
54
+ * @param tableName - Name of the table.
55
+ * @param tableData - Optional TableData containing headers and rows.
56
+ * @param updateQueryTable - Whether to update the associated queryTable part.
57
+ */
58
+ var updateTableInitialDataIfNeeded = function (zip, cellRangeRef, sheetPath, tablePath, sheetName, tableData, updateQueryTable) { return __awaiter(void 0, void 0, void 0, function () {
49
59
  var sheetsXmlString, newSheet, queryTableXmlString, newQueryTable, workbookXmlString, newWorkbook, tableXmlString, newTable;
50
60
  var _a, _b, _c, _d;
51
61
  return __generator(this, function (_e) {
@@ -54,14 +64,14 @@ var updateTableInitialDataIfNeeded = function (zip, tableData, updateQueryTable)
54
64
  if (!tableData) {
55
65
  return [2 /*return*/];
56
66
  }
57
- return [4 /*yield*/, ((_a = zip.file(constants_1.sheetsXmlPath)) === null || _a === void 0 ? void 0 : _a.async(constants_1.textResultType))];
67
+ return [4 /*yield*/, ((_a = zip.file(sheetPath)) === null || _a === void 0 ? void 0 : _a.async(constants_1.textResultType))];
58
68
  case 1:
59
69
  sheetsXmlString = _e.sent();
60
70
  if (sheetsXmlString === undefined) {
61
71
  throw new Error(constants_1.sheetsNotFoundErr);
62
72
  }
63
- newSheet = updateSheetsInitialData(sheetsXmlString, tableData);
64
- zip.file(constants_1.sheetsXmlPath, newSheet);
73
+ newSheet = updateSheetsInitialData(sheetsXmlString, tableData, cellRangeRef);
74
+ zip.file(sheetPath, newSheet);
65
75
  if (!updateQueryTable) return [3 /*break*/, 5];
66
76
  return [4 /*yield*/, ((_b = zip.file(constants_1.queryTableXmlPath)) === null || _b === void 0 ? void 0 : _b.async(constants_1.textResultType))];
67
77
  case 2:
@@ -79,22 +89,30 @@ var updateTableInitialDataIfNeeded = function (zip, tableData, updateQueryTable)
79
89
  if (workbookXmlString === undefined) {
80
90
  throw new Error(constants_1.sheetsNotFoundErr);
81
91
  }
82
- newWorkbook = updateWorkbookInitialData(workbookXmlString, tableData);
92
+ newWorkbook = updateWorkbookInitialData(workbookXmlString, sheetName + GenerateReferenceFromString(cellRangeRef));
83
93
  zip.file(constants_1.workbookXmlPath, newWorkbook);
84
94
  _e.label = 5;
85
- case 5: return [4 /*yield*/, ((_d = zip.file(constants_1.tableXmlPath)) === null || _d === void 0 ? void 0 : _d.async(constants_1.textResultType))];
95
+ case 5: return [4 /*yield*/, ((_d = zip.file(tablePath)) === null || _d === void 0 ? void 0 : _d.async(constants_1.textResultType))];
86
96
  case 6:
87
97
  tableXmlString = _e.sent();
88
98
  if (tableXmlString === undefined) {
89
99
  throw new Error(constants_1.tableNotFoundErr);
90
100
  }
91
- newTable = updateTablesInitialData(tableXmlString, tableData, updateQueryTable);
92
- zip.file(constants_1.tableXmlPath, newTable);
101
+ newTable = updateTablesInitialData(tableXmlString, tableData, cellRangeRef, updateQueryTable);
102
+ zip.file(tablePath, newTable);
93
103
  return [2 /*return*/];
94
104
  }
95
105
  });
96
106
  }); };
97
- var updateTablesInitialData = function (tableXmlString, tableData, updateQueryTable) {
107
+ /**
108
+ * Generate updated table XML string with new columns, reference, and filter range.
109
+ * @param tableXmlString - Original table XML.
110
+ * @param tableData - TableData containing column names.
111
+ * @param cellRangeRef - Cell range reference.
112
+ * @param updateQueryTable - Whether to include queryTable attributes.
113
+ * @returns Serialized XML string of the updated table.
114
+ */
115
+ var updateTablesInitialData = function (tableXmlString, tableData, cellRangeRef, updateQueryTable) {
98
116
  if (updateQueryTable === void 0) { updateQueryTable = false; }
99
117
  var parser = new xmldom_qsa_1.DOMParser();
100
118
  var serializer = new xmldom_qsa_1.XMLSerializer();
@@ -115,19 +133,24 @@ var updateTablesInitialData = function (tableXmlString, tableData, updateQueryTa
115
133
  tableColumns.setAttribute(constants_1.elementAttributes.count, tableData.columnNames.length.toString());
116
134
  tableDoc
117
135
  .getElementsByTagName(constants_1.element.table)[0]
118
- .setAttribute(constants_1.elementAttributes.reference, "A1:".concat(documentUtils_1.default.getCellReferenceRelative(tableData.columnNames.length - 1, tableData.rows.length + 1)));
136
+ .setAttribute(constants_1.elementAttributes.reference, cellRangeRef);
119
137
  tableDoc
120
138
  .getElementsByTagName(constants_1.element.autoFilter)[0]
121
- .setAttribute(constants_1.elementAttributes.reference, "A1:".concat(documentUtils_1.default.getCellReferenceRelative(tableData.columnNames.length - 1, tableData.rows.length + 1)));
139
+ .setAttribute(constants_1.elementAttributes.reference, cellRangeRef);
122
140
  return serializer.serializeToString(tableDoc);
123
141
  };
124
- var updateWorkbookInitialData = function (workbookXmlString, tableData) {
142
+ /**
143
+ * Update the definedName element in workbook XML to a custom name.
144
+ * @param workbookXmlString - Original workbook XML string.
145
+ * @param customDefinedName - New defined name text content (e.g. "!$A$1:$C$5").
146
+ * @returns Serialized XML string of the updated workbook.
147
+ */
148
+ var updateWorkbookInitialData = function (workbookXmlString, customDefinedName) {
125
149
  var newParser = new xmldom_qsa_1.DOMParser();
126
150
  var newSerializer = new xmldom_qsa_1.XMLSerializer();
127
151
  var workbookDoc = newParser.parseFromString(workbookXmlString, constants_1.xmlTextResultType);
128
152
  var definedName = workbookDoc.getElementsByTagName(constants_1.element.definedName)[0];
129
- definedName.textContent =
130
- constants_1.defaults.sheetName + "!$A$1:".concat(documentUtils_1.default.getCellReferenceAbsolute(tableData.columnNames.length - 1, tableData.rows.length + 1));
153
+ definedName.textContent = customDefinedName;
131
154
  return newSerializer.serializeToString(workbookDoc);
132
155
  };
133
156
  var updateQueryTablesInitialData = function (queryTableXmlString, tableData) {
@@ -147,42 +170,64 @@ var updateQueryTablesInitialData = function (queryTableXmlString, tableData) {
147
170
  queryTableDoc.getElementsByTagName(constants_1.element.queryTableRefresh)[0].setAttribute(constants_1.elementAttributes.nextId, (tableData.columnNames.length + 1).toString());
148
171
  return serializer.serializeToString(queryTableDoc);
149
172
  };
150
- var updateSheetsInitialData = function (sheetsXmlString, tableData) {
173
+ /**
174
+ * Update sheet XML with header row and data rows based on TableData.
175
+ * @param sheetsXmlString - Original sheet XML string.
176
+ * @param tableData - TableData containing headers and rows.
177
+ * @param cellRangeRef - Cell range reference.
178
+ * @returns Serialized XML string of the updated sheet.
179
+ */
180
+ var updateSheetsInitialData = function (sheetsXmlString, tableData, cellRangeRef) {
181
+ var _a = documentUtils_1.default.GetStartPosition(cellRangeRef), row = _a.row, column = _a.column;
151
182
  var parser = new xmldom_qsa_1.DOMParser();
152
183
  var serializer = new xmldom_qsa_1.XMLSerializer();
153
184
  var sheetsDoc = parser.parseFromString(sheetsXmlString, constants_1.xmlTextResultType);
154
185
  var sheetData = sheetsDoc.getElementsByTagName(constants_1.element.sheetData)[0];
155
186
  sheetData.textContent = "";
156
- var rowIndex = 0;
157
187
  var columnRow = sheetsDoc.createElementNS(sheetsDoc.documentElement.namespaceURI, constants_1.element.row);
158
- columnRow.setAttribute(constants_1.elementAttributes.row, (rowIndex + 1).toString());
159
- columnRow.setAttribute(constants_1.elementAttributes.spans, "1:" + tableData.columnNames.length);
188
+ columnRow.setAttribute(constants_1.elementAttributes.row, row.toString());
189
+ columnRow.setAttribute(constants_1.elementAttributes.spans, column + ":" + (column + tableData.columnNames.length - 1));
160
190
  columnRow.setAttribute(constants_1.elementAttributes.x14acDyDescent, "0.3");
161
191
  tableData.columnNames.forEach(function (col, colIndex) {
162
- columnRow.appendChild(documentUtils_1.default.createCell(sheetsDoc, colIndex, rowIndex, col));
192
+ columnRow.appendChild(documentUtils_1.default.createCell(sheetsDoc, colIndex + column - 1, row - 1, col));
163
193
  });
164
194
  sheetData.appendChild(columnRow);
165
- rowIndex++;
166
- tableData.rows.forEach(function (row) {
195
+ row++;
196
+ tableData.rows.forEach(function (_row) {
167
197
  var newRow = sheetsDoc.createElementNS(sheetsDoc.documentElement.namespaceURI, constants_1.element.row);
168
- newRow.setAttribute(constants_1.elementAttributes.row, (rowIndex + 1).toString());
169
- newRow.setAttribute(constants_1.elementAttributes.spans, "1:" + row.length);
198
+ newRow.setAttribute(constants_1.elementAttributes.row, row.toString());
199
+ newRow.setAttribute(constants_1.elementAttributes.spans, column + ":" + (column + tableData.columnNames.length - 1));
170
200
  newRow.setAttribute(constants_1.elementAttributes.x14acDyDescent, "0.3");
171
- row.forEach(function (cellContent, colIndex) {
172
- newRow.appendChild(documentUtils_1.default.createCell(sheetsDoc, colIndex, rowIndex, cellContent));
201
+ _row.forEach(function (cellContent, colIndex) {
202
+ newRow.appendChild(documentUtils_1.default.createCell(sheetsDoc, colIndex + column - 1, row - 1, cellContent));
173
203
  });
174
204
  sheetData.appendChild(newRow);
175
- rowIndex++;
205
+ row++;
176
206
  });
177
- var reference = documentUtils_1.default.getTableReference(tableData.rows[0].length - 1, tableData.rows.length + 1);
178
- sheetsDoc.getElementsByTagName(constants_1.element.dimension)[0].setAttribute(constants_1.elementAttributes.reference, reference);
179
- sheetsDoc.getElementsByTagName(constants_1.element.selection)[0].setAttribute(constants_1.elementAttributes.sqref, reference);
207
+ sheetsDoc.getElementsByTagName(constants_1.element.dimension)[0].setAttribute(constants_1.elementAttributes.reference, cellRangeRef);
208
+ sheetsDoc.getElementsByTagName(constants_1.element.selection)[0].setAttribute(constants_1.elementAttributes.sqref, cellRangeRef);
180
209
  return serializer.serializeToString(sheetsDoc);
181
210
  };
211
+ /**
212
+ * Add Excel-style dollar signs and a '!' prefix to a cell range.
213
+ * Converts "A1:B2" into "!$A$1:$B$2".
214
+ * @param cellRangeRef - Range reference string without dollar signs.
215
+ * @returns Range with dollar signs and prefix.
216
+ */
217
+ var GenerateReferenceFromString = function (cellRangeRef) {
218
+ return "!" + cellRangeRef.split(":").map(function (part) {
219
+ var match = part.match(/^([A-Za-z]+)(\d+)$/);
220
+ if (match) {
221
+ var col = match[1], row = match[2];
222
+ return "$".concat(col.toUpperCase(), "$").concat(row);
223
+ }
224
+ }).join(":");
225
+ };
182
226
  exports.default = {
183
227
  updateTableInitialDataIfNeeded: updateTableInitialDataIfNeeded,
184
228
  updateSheetsInitialData: updateSheetsInitialData,
185
229
  updateWorkbookInitialData: updateWorkbookInitialData,
186
230
  updateTablesInitialData: updateTablesInitialData,
187
231
  updateQueryTablesInitialData: updateQueryTablesInitialData,
232
+ GenerateReferenceFromString: GenerateReferenceFromString,
188
233
  };
@@ -76,33 +76,60 @@ var updateDocProps = function (zip, docProps) {
76
76
  });
77
77
  });
78
78
  };
79
+ var removeLabelInfoRelationship = function (doc, relationships) {
80
+ // Find and remove LabelInfo.xml relationship
81
+ var relationshipElements = doc.getElementsByTagName(constants_1.element.relationship);
82
+ for (var i = 0; i < relationshipElements.length; i++) {
83
+ var rel = relationshipElements[i];
84
+ if (rel.getAttribute(constants_1.elementAttributes.target) === constants_1.labelInfoXmlPath) {
85
+ relationships.removeChild(rel);
86
+ break;
87
+ }
88
+ }
89
+ };
90
+ var updateRelationshipIds = function (doc) {
91
+ // Update relationship IDs
92
+ var relationshipElements = doc.getElementsByTagName(constants_1.element.relationship);
93
+ for (var i = 0; i < relationshipElements.length; i++) {
94
+ var rel = relationshipElements[i];
95
+ var target = rel.getAttribute(constants_1.elementAttributes.target);
96
+ if (target === constants_1.workbookXmlPath) {
97
+ rel.setAttribute(constants_1.elementAttributes.Id, constants_1.elementAttributes.relationId1);
98
+ }
99
+ else if (target === constants_1.docPropsCoreXmlPath) {
100
+ rel.setAttribute(constants_1.elementAttributes.Id, constants_1.elementAttributes.relationId2);
101
+ }
102
+ else if (target === constants_1.docPropsAppXmlPath) {
103
+ rel.setAttribute(constants_1.elementAttributes.Id, constants_1.elementAttributes.relationId3);
104
+ }
105
+ }
106
+ };
79
107
  var clearLabelInfo = function (zip) { return __awaiter(void 0, void 0, void 0, function () {
80
- var relsString, parser, doc, relationships, element, serializer, newDoc;
81
- var _a, _b, _c, _d;
82
- return __generator(this, function (_e) {
83
- switch (_e.label) {
108
+ var relsString, parser, doc, relationshipsList, relationships, serializer, newDoc;
109
+ var _a;
110
+ return __generator(this, function (_b) {
111
+ switch (_b.label) {
84
112
  case 0:
85
113
  // remove docMetadata folder that contains only LabelInfo.xml in template file.
86
114
  zip.remove(constants_1.docMetadataXmlPath);
87
115
  return [4 /*yield*/, ((_a = zip.file(constants_1.relsXmlPath)) === null || _a === void 0 ? void 0 : _a.async(constants_1.textResultType))];
88
116
  case 1:
89
- relsString = _e.sent();
117
+ relsString = _b.sent();
90
118
  if (relsString === undefined) {
91
119
  throw new Error(constants_1.relsNotFoundErr);
92
120
  }
93
121
  parser = new xmldom_qsa_1.DOMParser();
94
122
  doc = parser.parseFromString(relsString, constants_1.xmlTextResultType);
95
- relationships = doc.querySelector("Relationships");
96
- if (relationships === null) {
97
- throw new Error(constants_1.unexpectedErr);
123
+ relationshipsList = doc.getElementsByTagName(constants_1.element.relationships);
124
+ if (!relationshipsList || relationshipsList.length === 0) {
125
+ throw new Error(constants_1.relationshipErr);
98
126
  }
99
- element = relationships.querySelector('Relationship[Target="docMetadata/LabelInfo.xml"]');
100
- if (element) {
101
- relationships.removeChild(element);
127
+ relationships = relationshipsList[0];
128
+ if (!relationships) {
129
+ throw new Error(constants_1.relationshipErr);
102
130
  }
103
- (_b = relationships.querySelector('Relationship[Target="xl/workbook.xml"]')) === null || _b === void 0 ? void 0 : _b.setAttribute("Id", "rId1");
104
- (_c = relationships.querySelector('Relationship[Target="docProps/core.xml"]')) === null || _c === void 0 ? void 0 : _c.setAttribute("Id", "rId2");
105
- (_d = relationships.querySelector('Relationship[Target="docProps/app.xml"]')) === null || _d === void 0 ? void 0 : _d.setAttribute("Id", "rId3");
131
+ removeLabelInfoRelationship(doc, relationships);
132
+ updateRelationshipIds(doc);
106
133
  serializer = new xmldom_qsa_1.XMLSerializer();
107
134
  newDoc = serializer.serializeToString(doc);
108
135
  zip.file(constants_1.relsXmlPath, newDoc);
@@ -277,6 +304,118 @@ var updatePivotTable = function (tableXmlString, connectionId, refreshOnOpen) {
277
304
  }
278
305
  return { isPivotTableUpdated: isPivotTableUpdated, newPivotTable: newPivotTable };
279
306
  };
307
+ /**
308
+ * Retrieves the target path of a sheet from workbook relationships by its relationship ID.
309
+ */
310
+ function getSheetPathFromXlRelId(zip, rId) {
311
+ return __awaiter(this, void 0, void 0, function () {
312
+ var relsFile, relsString, relsDoc, relationships, target, i, el;
313
+ return __generator(this, function (_a) {
314
+ switch (_a.label) {
315
+ case 0:
316
+ relsFile = zip.file(constants_1.workbookRelsXmlPath);
317
+ if (!relsFile) {
318
+ throw new Error(constants_1.xlRelsNotFoundErr);
319
+ }
320
+ return [4 /*yield*/, relsFile.async(constants_1.textResultType)];
321
+ case 1:
322
+ relsString = _a.sent();
323
+ relsDoc = new xmldom_qsa_1.DOMParser().parseFromString(relsString, constants_1.xmlTextResultType);
324
+ relationships = relsDoc.getElementsByTagName("Relationship");
325
+ target = null;
326
+ for (i = 0; i < relationships.length; i++) {
327
+ el = relationships[i];
328
+ if (el && el.getAttribute && el.getAttribute("Id") === rId) {
329
+ target = el.getAttribute(constants_1.elementAttributes.target);
330
+ break;
331
+ }
332
+ }
333
+ if (!target) {
334
+ throw new Error("Relationship not found or missing Target for Id: ".concat(rId));
335
+ }
336
+ return [2 /*return*/, target];
337
+ }
338
+ });
339
+ });
340
+ }
341
+ // get sheet name from workbook
342
+ var getSheetPathByNameFromZip = function (zip, sheetName) { return __awaiter(void 0, void 0, void 0, function () {
343
+ var workbookXmlString, parser, doc, sheetElements, i, rId;
344
+ var _a;
345
+ return __generator(this, function (_b) {
346
+ switch (_b.label) {
347
+ case 0: return [4 /*yield*/, ((_a = zip.file(constants_1.workbookXmlPath)) === null || _a === void 0 ? void 0 : _a.async("text"))];
348
+ case 1:
349
+ workbookXmlString = _b.sent();
350
+ if (!workbookXmlString) {
351
+ throw new Error(constants_1.WorkbookNotFoundERR);
352
+ }
353
+ parser = new xmldom_qsa_1.DOMParser();
354
+ doc = parser.parseFromString(workbookXmlString, constants_1.xmlTextResultType);
355
+ sheetElements = doc.getElementsByTagName(constants_1.element.sheet);
356
+ for (i = 0; i < sheetElements.length; i++) {
357
+ if (sheetElements[i].getAttribute(constants_1.elementAttributes.name) === sheetName) {
358
+ rId = sheetElements[i].getAttribute(constants_1.elementAttributes.relationId);
359
+ if (rId) {
360
+ return [2 /*return*/, getSheetPathFromXlRelId(zip, rId)];
361
+ }
362
+ }
363
+ }
364
+ throw new Error("Sheet with name ".concat(sheetName, " not found"));
365
+ }
366
+ });
367
+ }); };
368
+ // get definedName
369
+ var getReferenceFromTable = function (zip, tablePath) { return __awaiter(void 0, void 0, void 0, function () {
370
+ var tableXmlString, parser, doc, tableElements, reference;
371
+ var _a, _b;
372
+ return __generator(this, function (_c) {
373
+ switch (_c.label) {
374
+ case 0: return [4 /*yield*/, ((_a = zip.file(tablePath)) === null || _a === void 0 ? void 0 : _a.async("text"))];
375
+ case 1:
376
+ tableXmlString = _c.sent();
377
+ if (!tableXmlString) {
378
+ throw new Error(constants_1.WorkbookNotFoundERR);
379
+ }
380
+ parser = new xmldom_qsa_1.DOMParser();
381
+ doc = parser.parseFromString(tableXmlString, constants_1.xmlTextResultType);
382
+ tableElements = doc.getElementsByTagName(constants_1.element.table);
383
+ reference = (_b = tableElements[0]) === null || _b === void 0 ? void 0 : _b.getAttribute(constants_1.elementAttributes.reference);
384
+ if (!reference) {
385
+ throw new Error(constants_1.tableReferenceNotFoundErr);
386
+ }
387
+ return [2 /*return*/, reference.split(":")[0]]; // Return the start cell reference (e.g., "A1" from "A1:B10")
388
+ }
389
+ });
390
+ }); };
391
+ var findTablePathFromZip = function (zip, targetTableName) { return __awaiter(void 0, void 0, void 0, function () {
392
+ var tablesFolder, tableFilePromises, tableFiles, parser, _i, tableFiles_1, _a, path, content, doc, tableElem;
393
+ return __generator(this, function (_b) {
394
+ switch (_b.label) {
395
+ case 0:
396
+ tablesFolder = zip.folder("xl/tables");
397
+ if (!tablesFolder)
398
+ return [2 /*return*/, ""];
399
+ tableFilePromises = [];
400
+ tablesFolder.forEach(function (relativePath, file) {
401
+ tableFilePromises.push(file.async(constants_1.textResultType).then(function (content) { return ({ path: relativePath, content: content }); }));
402
+ });
403
+ return [4 /*yield*/, Promise.all(tableFilePromises)];
404
+ case 1:
405
+ tableFiles = _b.sent();
406
+ parser = new xmldom_qsa_1.DOMParser();
407
+ for (_i = 0, tableFiles_1 = tableFiles; _i < tableFiles_1.length; _i++) {
408
+ _a = tableFiles_1[_i], path = _a.path, content = _a.content;
409
+ doc = parser.parseFromString(content, constants_1.xmlTextResultType);
410
+ tableElem = doc.getElementsByTagName(constants_1.element.table)[0];
411
+ if (tableElem && tableElem.getAttribute(constants_1.elementAttributes.name) === targetTableName) {
412
+ return [2 /*return*/, path];
413
+ }
414
+ }
415
+ throw new Error(constants_1.tableNotFoundErr);
416
+ }
417
+ });
418
+ }); };
280
419
  exports.default = {
281
420
  updateDocProps: updateDocProps,
282
421
  clearLabelInfo: clearLabelInfo,
@@ -286,4 +425,7 @@ exports.default = {
286
425
  updatePivotTablesandQueryTables: updatePivotTablesandQueryTables,
287
426
  updateQueryTable: updateQueryTable,
288
427
  updatePivotTable: updatePivotTable,
428
+ getSheetPathByNameFromZip: getSheetPathByNameFromZip,
429
+ getReferenceFromTable: getReferenceFromTable,
430
+ findTablePathFromZip: findTablePathFromZip,
289
431
  };
@@ -44,26 +44,63 @@ Object.defineProperty(exports, "__esModule", { value: true });
44
44
  var constants_1 = require("./constants");
45
45
  var mashupDocumentParser_1 = require("./mashupDocumentParser");
46
46
  var pqUtils_1 = __importDefault(require("./pqUtils"));
47
- var xmlInnerPartsUtils_1 = __importDefault(require("./xmlInnerPartsUtils"));
48
47
  var tableUtils_1 = __importDefault(require("./tableUtils"));
48
+ var xmlInnerPartsUtils_1 = __importDefault(require("./xmlInnerPartsUtils"));
49
+ var documentUtils_1 = __importDefault(require("./documentUtils"));
49
50
  var updateWorkbookDataAndConfigurations = function (zip, fileConfigs, tableData, updateQueryTable) {
50
51
  if (updateQueryTable === void 0) { updateQueryTable = false; }
51
52
  return __awaiter(void 0, void 0, void 0, function () {
52
- return __generator(this, function (_a) {
53
- switch (_a.label) {
54
- case 0: return [4 /*yield*/, xmlInnerPartsUtils_1.default.updateDocProps(zip, fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.docProps)];
53
+ var sheetName, tablePath, sheetPath, templateSettings, sheetLocation, _a, cellRangeRef, _b, row, column, endColumn, endRow;
54
+ return __generator(this, function (_c) {
55
+ switch (_c.label) {
56
+ case 0:
57
+ sheetName = constants_1.defaults.sheetName;
58
+ tablePath = constants_1.tableXmlPath;
59
+ sheetPath = constants_1.sheetsXmlPath;
60
+ if (!((fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.templateFile) !== undefined)) return [3 /*break*/, 4];
61
+ templateSettings = fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.templateSettings;
62
+ if (!((templateSettings === null || templateSettings === void 0 ? void 0 : templateSettings.sheetName) !== undefined)) return [3 /*break*/, 2];
63
+ return [4 /*yield*/, xmlInnerPartsUtils_1.default.getSheetPathByNameFromZip(zip, templateSettings.sheetName)];
55
64
  case 1:
56
- _a.sent();
57
- if (!((fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.templateFile) === undefined)) return [3 /*break*/, 3];
65
+ sheetLocation = _c.sent();
66
+ sheetName = templateSettings.sheetName;
67
+ sheetPath = "xl/" + sheetLocation;
68
+ _c.label = 2;
69
+ case 2:
70
+ if (!((templateSettings === null || templateSettings === void 0 ? void 0 : templateSettings.tableName) !== undefined)) return [3 /*break*/, 4];
71
+ _a = constants_1.tablesFolderPath;
72
+ return [4 /*yield*/, xmlInnerPartsUtils_1.default.findTablePathFromZip(zip, templateSettings === null || templateSettings === void 0 ? void 0 : templateSettings.tableName)];
73
+ case 3:
74
+ tablePath = _a + (_c.sent());
75
+ _c.label = 4;
76
+ case 4:
77
+ cellRangeRef = "A1";
78
+ if (!((fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.templateFile) !== undefined)) return [3 /*break*/, 6];
79
+ return [4 /*yield*/, xmlInnerPartsUtils_1.default.getReferenceFromTable(zip, tablePath)];
80
+ case 5:
81
+ cellRangeRef = _c.sent();
82
+ _c.label = 6;
83
+ case 6:
84
+ if (tableData) {
85
+ _b = documentUtils_1.default.GetStartPosition(cellRangeRef), row = _b.row, column = _b.column;
86
+ endColumn = column - 1 + tableData.columnNames.length;
87
+ endRow = row - 1 + tableData.rows.length;
88
+ // Extend the cell range to include the entire table span
89
+ cellRangeRef += ":".concat(documentUtils_1.default.getCellReferenceRelative(endColumn - 1, endRow + 1));
90
+ }
91
+ return [4 /*yield*/, xmlInnerPartsUtils_1.default.updateDocProps(zip, fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.docProps)];
92
+ case 7:
93
+ _c.sent();
94
+ if (!((fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.templateFile) === undefined)) return [3 /*break*/, 9];
58
95
  // If we are using our base template, we need to clear label info
59
96
  return [4 /*yield*/, xmlInnerPartsUtils_1.default.clearLabelInfo(zip)];
60
- case 2:
97
+ case 8:
61
98
  // If we are using our base template, we need to clear label info
62
- _a.sent();
63
- _a.label = 3;
64
- case 3: return [4 /*yield*/, tableUtils_1.default.updateTableInitialDataIfNeeded(zip, tableData, updateQueryTable)];
65
- case 4:
66
- _a.sent();
99
+ _c.sent();
100
+ _c.label = 9;
101
+ case 9: return [4 /*yield*/, tableUtils_1.default.updateTableInitialDataIfNeeded(zip, cellRangeRef, sheetPath, tablePath, sheetPath, tableData, updateQueryTable)];
102
+ case 10:
103
+ _c.sent();
67
104
  return [2 /*return*/];
68
105
  }
69
106
  });
@@ -89,8 +126,8 @@ var updateWorkbookPowerQueryDocument = function (zip, queryName, queryMashupDoc)
89
126
  }
90
127
  });
91
128
  }); };
92
- var updateWorkbookSingleQueryAttributes = function (zip, queryName, refreshOnOpen) { return __awaiter(void 0, void 0, void 0, function () {
93
- var connectionsXmlString, _a, connectionId, connectionXmlFileString, sharedStringsXmlString, _b, sharedStringIndex, newSharedStrings, sheetsXmlString, worksheetString;
129
+ var updateWorkbookSingleQueryAttributes = function (zip, queryName, refreshOnOpen, sheetName) { return __awaiter(void 0, void 0, void 0, function () {
130
+ var connectionsXmlString, _a, connectionId, connectionXmlFileString, sharedStringsXmlString, _b, sharedStringIndex, newSharedStrings, sheetPath, sheetLocation, sheetsXmlString, worksheetString;
94
131
  var _c, _d, _e;
95
132
  return __generator(this, function (_f) {
96
133
  switch (_f.label) {
@@ -110,17 +147,24 @@ var updateWorkbookSingleQueryAttributes = function (zip, queryName, refreshOnOpe
110
147
  }
111
148
  _b = xmlInnerPartsUtils_1.default.updateSharedStrings(sharedStringsXmlString, queryName), sharedStringIndex = _b.sharedStringIndex, newSharedStrings = _b.newSharedStrings;
112
149
  zip.file(constants_1.sharedStringsXmlPath, newSharedStrings);
113
- return [4 /*yield*/, ((_e = zip.file(constants_1.sheetsXmlPath)) === null || _e === void 0 ? void 0 : _e.async(constants_1.textResultType))];
150
+ sheetPath = constants_1.sheetsXmlPath;
151
+ if (!(sheetName !== undefined)) return [3 /*break*/, 4];
152
+ return [4 /*yield*/, xmlInnerPartsUtils_1.default.getSheetPathByNameFromZip(zip, sheetName)];
114
153
  case 3:
154
+ sheetLocation = _f.sent();
155
+ sheetPath = "xl/" + sheetLocation;
156
+ _f.label = 4;
157
+ case 4: return [4 /*yield*/, ((_e = zip.file(sheetPath)) === null || _e === void 0 ? void 0 : _e.async(constants_1.textResultType))];
158
+ case 5:
115
159
  sheetsXmlString = _f.sent();
116
160
  if (sheetsXmlString === undefined) {
117
161
  throw new Error(constants_1.sheetsNotFoundErr);
118
162
  }
119
163
  worksheetString = xmlInnerPartsUtils_1.default.updateWorksheet(sheetsXmlString, sharedStringIndex.toString());
120
- zip.file(constants_1.sheetsXmlPath, worksheetString);
164
+ zip.file(sheetPath, worksheetString);
121
165
  // Update tables
122
166
  return [4 /*yield*/, xmlInnerPartsUtils_1.default.updatePivotTablesandQueryTables(zip, queryName, refreshOnOpen, connectionId)];
123
- case 4:
167
+ case 6:
124
168
  // Update tables
125
169
  _f.sent();
126
170
  return [2 /*return*/];