@microsoft/connected-workbooks 2.1.16-beta → 2.1.25

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.
Files changed (68) hide show
  1. package/README.md +83 -15
  2. package/dist/generators.js +1 -1
  3. package/dist/gridParser.js +58 -0
  4. package/dist/gridUtils.js +58 -0
  5. package/dist/index.d.ts +6 -3
  6. package/dist/index.js +26 -6
  7. package/dist/src/generators.js +14 -0
  8. package/dist/src/types.js +28 -0
  9. package/dist/src/utils/arrayUtils.js +46 -0
  10. package/dist/{constants.js → src/utils/constants.js} +139 -131
  11. package/dist/src/utils/documentUtils.js +102 -0
  12. package/dist/src/utils/gridUtils.js +103 -0
  13. package/dist/src/utils/htmlUtils.js +19 -0
  14. package/dist/src/utils/index.js +24 -0
  15. package/dist/src/utils/mashupDocumentParser.js +145 -0
  16. package/dist/src/utils/pqUtils.js +100 -0
  17. package/dist/src/utils/tableUtils.js +143 -0
  18. package/dist/src/utils/xmlInnerPartsUtils.js +200 -0
  19. package/dist/src/utils/xmlPartsUtils.js +64 -0
  20. package/dist/src/workbookTemplate.js +7 -0
  21. package/dist/tests/arrayUtils.test.js +65 -0
  22. package/dist/tests/documentUtils.test.js +35 -0
  23. package/dist/tests/gridUtils.test.js +168 -0
  24. package/dist/tests/htmlUtils.test.js +109 -0
  25. package/dist/tests/mashupDocumentParser.test.js +59 -0
  26. package/dist/tests/mocks/PqMock.js +7 -0
  27. package/dist/tests/mocks/index.js +24 -0
  28. package/dist/tests/mocks/section1mSimpleQueryMock.js +18 -0
  29. package/dist/tests/mocks/xmlMocks.js +12 -0
  30. package/dist/tests/tableUtils.test.js +63 -0
  31. package/dist/tests/workbookQueryTemplate.test.js +64 -0
  32. package/dist/tests/workbookTableTemplate.test.js +54 -0
  33. package/dist/tests/xmlInnerPartsUtils.test.js +51 -0
  34. package/dist/types.d.ts +10 -11
  35. package/dist/types.js +0 -1
  36. package/dist/utils/constants.js +15 -5
  37. package/dist/utils/documentUtils.js +10 -9
  38. package/dist/utils/gridUtils.js +103 -0
  39. package/dist/utils/htmlUtils.js +5 -11
  40. package/dist/utils/index.js +5 -1
  41. package/dist/utils/mashupDocumentParser.js +102 -123
  42. package/dist/utils/pqUtils.js +9 -10
  43. package/dist/utils/tableUtils.js +31 -34
  44. package/dist/utils/xmlInnerPartsUtils.js +11 -9
  45. package/dist/utils/xmlPartsUtils.js +7 -5
  46. package/dist/workbookManager.d.ts +5 -8
  47. package/dist/workbookManager.js +17 -31
  48. package/dist/workbookTemplate.js +3 -5
  49. package/package.json +22 -7
  50. package/dist/GridParser.d.ts +0 -6
  51. package/dist/GridParser.js +0 -55
  52. package/dist/TableDataParserFactory.d.ts +0 -4
  53. package/dist/TableDataParserFactory.js +0 -15
  54. package/dist/constants.d.ts +0 -121
  55. package/dist/generators.d.ts +0 -3
  56. package/dist/mashupDocumentParser.d.ts +0 -7
  57. package/dist/mashupDocumentParser.js +0 -169
  58. package/dist/utils/arrayUtils.d.ts +0 -16
  59. package/dist/utils/constants.d.ts +0 -121
  60. package/dist/utils/documentUtils.d.ts +0 -15
  61. package/dist/utils/htmlUtils.d.ts +0 -1
  62. package/dist/utils/index.d.ts +0 -6
  63. package/dist/utils/mashupDocumentParser.d.ts +0 -7
  64. package/dist/utils/pqUtils.d.ts +0 -15
  65. package/dist/utils/tableUtils.d.ts +0 -10
  66. package/dist/utils/xmlInnerPartsUtils.d.ts +0 -24
  67. package/dist/utils/xmlPartsUtils.d.ts +0 -8
  68. package/dist/workbookTemplate.d.ts +0 -4
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT license.
4
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
5
+ if (k2 === undefined) k2 = k;
6
+ var desc = Object.getOwnPropertyDescriptor(m, k);
7
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
8
+ desc = { enumerable: true, get: function() { return m[k]; } };
9
+ }
10
+ Object.defineProperty(o, k2, desc);
11
+ }) : (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ o[k2] = m[k];
14
+ }));
15
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
16
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
17
+ }) : function(o, v) {
18
+ o["default"] = v;
19
+ });
20
+ var __importStar = (this && this.__importStar) || function (mod) {
21
+ if (mod && mod.__esModule) return mod;
22
+ var result = {};
23
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
24
+ __setModuleDefault(result, mod);
25
+ return result;
26
+ };
27
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
28
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
29
+ return new (P || (P = Promise))(function (resolve, reject) {
30
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
31
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
32
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
33
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
34
+ });
35
+ };
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.editSingleQueryMetadata = exports.getPackageComponents = exports.replaceSingleQuery = void 0;
41
+ const base64 = __importStar(require("base64-js"));
42
+ const jszip_1 = __importDefault(require("jszip"));
43
+ const constants_1 = require("./constants");
44
+ const _1 = require(".");
45
+ const replaceSingleQuery = (base64Str, queryName, queryMashupDoc) => __awaiter(void 0, void 0, void 0, function* () {
46
+ const { version, packageOPC, permissionsSize, permissions, metadata, endBuffer } = (0, exports.getPackageComponents)(base64Str);
47
+ const newPackageBuffer = yield editSingleQueryPackage(packageOPC, queryMashupDoc);
48
+ const packageSizeBuffer = _1.arrayUtils.getInt32Buffer(newPackageBuffer.byteLength);
49
+ const permissionsSizeBuffer = _1.arrayUtils.getInt32Buffer(permissionsSize);
50
+ const newMetadataBuffer = (0, exports.editSingleQueryMetadata)(metadata, { queryName });
51
+ const metadataSizeBuffer = _1.arrayUtils.getInt32Buffer(newMetadataBuffer.byteLength);
52
+ const newMashup = _1.arrayUtils.concatArrays(version, packageSizeBuffer, newPackageBuffer, permissionsSizeBuffer, permissions, metadataSizeBuffer, newMetadataBuffer, endBuffer);
53
+ return base64.fromByteArray(newMashup);
54
+ });
55
+ exports.replaceSingleQuery = replaceSingleQuery;
56
+ const getPackageComponents = (base64Str) => {
57
+ const buffer = base64.toByteArray(base64Str).buffer;
58
+ const mashupArray = new _1.arrayUtils.ArrayReader(buffer);
59
+ const version = mashupArray.getBytes(4);
60
+ const packageSize = mashupArray.getInt32();
61
+ const packageOPC = mashupArray.getBytes(packageSize);
62
+ const permissionsSize = mashupArray.getInt32();
63
+ const permissions = mashupArray.getBytes(permissionsSize);
64
+ const metadataSize = mashupArray.getInt32();
65
+ const metadata = mashupArray.getBytes(metadataSize);
66
+ const endBuffer = mashupArray.getBytes();
67
+ return {
68
+ version,
69
+ packageOPC,
70
+ permissionsSize,
71
+ permissions,
72
+ metadata,
73
+ endBuffer,
74
+ };
75
+ };
76
+ exports.getPackageComponents = getPackageComponents;
77
+ const editSingleQueryPackage = (packageOPC, queryMashupDoc) => __awaiter(void 0, void 0, void 0, function* () {
78
+ const packageZip = yield jszip_1.default.loadAsync(packageOPC);
79
+ setSection1m(queryMashupDoc, packageZip);
80
+ return yield packageZip.generateAsync({ type: constants_1.uint8ArrayType });
81
+ });
82
+ const setSection1m = (queryMashupDoc, zip) => {
83
+ var _a;
84
+ if (!((_a = zip.file(constants_1.section1mPath)) === null || _a === void 0 ? void 0 : _a.async(constants_1.textResultType))) {
85
+ throw new Error(constants_1.formulaSectionNotFoundErr);
86
+ }
87
+ const newSection1m = queryMashupDoc;
88
+ zip.file(constants_1.section1mPath, newSection1m, {
89
+ compression: constants_1.emptyValue,
90
+ });
91
+ };
92
+ const editSingleQueryMetadata = (metadataArray, metadata) => {
93
+ //extract metadataXml
94
+ const mashupArray = new _1.arrayUtils.ArrayReader(metadataArray.buffer);
95
+ const metadataVersion = mashupArray.getBytes(4);
96
+ const metadataXmlSize = mashupArray.getInt32();
97
+ const metadataXml = mashupArray.getBytes(metadataXmlSize);
98
+ const endBuffer = mashupArray.getBytes();
99
+ //parse metdataXml
100
+ const textDecoder = new TextDecoder();
101
+ const metadataString = textDecoder.decode(metadataXml);
102
+ const parser = new DOMParser();
103
+ const serializer = new XMLSerializer();
104
+ const parsedMetadata = parser.parseFromString(metadataString, constants_1.xmlTextResultType);
105
+ // Update InfoPaths to new QueryName
106
+ const itemPaths = parsedMetadata.getElementsByTagName(constants_1.element.itemPath);
107
+ if (itemPaths && itemPaths.length) {
108
+ for (let i = 0; i < itemPaths.length; i++) {
109
+ const itemPath = itemPaths[i];
110
+ const content = itemPath.innerHTML;
111
+ if (content.includes(constants_1.section1PathPrefix)) {
112
+ const strArr = content.split(constants_1.divider);
113
+ strArr[1] = encodeURIComponent(metadata.queryName);
114
+ const newContent = strArr.join(constants_1.divider);
115
+ itemPath.textContent = newContent;
116
+ }
117
+ }
118
+ }
119
+ const entries = parsedMetadata.getElementsByTagName(constants_1.element.entry);
120
+ if (entries && entries.length) {
121
+ for (let i = 0; i < entries.length; i++) {
122
+ const entry = entries[i];
123
+ const entryAttributes = entry.attributes;
124
+ const entryAttributesArr = [...entryAttributes];
125
+ const entryProp = entryAttributesArr.find((prop) => {
126
+ return (prop === null || prop === void 0 ? void 0 : prop.name) === constants_1.elementAttributes.type;
127
+ });
128
+ if ((entryProp === null || entryProp === void 0 ? void 0 : entryProp.nodeValue) == constants_1.elementAttributes.resultType) {
129
+ entry.setAttribute(constants_1.elementAttributes.value, constants_1.elementAttributesValues.tableResultType());
130
+ }
131
+ if ((entryProp === null || entryProp === void 0 ? void 0 : entryProp.nodeValue) == constants_1.elementAttributes.fillLastUpdated) {
132
+ const nowTime = new Date().toISOString();
133
+ entry.setAttribute(constants_1.elementAttributes.value, (constants_1.elementAttributes.day + nowTime).replace(/Z/, "0000Z"));
134
+ }
135
+ }
136
+ }
137
+ // Convert new metadataXml to Uint8Array
138
+ const newMetadataString = serializer.serializeToString(parsedMetadata);
139
+ const encoder = new TextEncoder();
140
+ const newMetadataXml = encoder.encode(newMetadataString);
141
+ const newMetadataXmlSize = _1.arrayUtils.getInt32Buffer(newMetadataXml.byteLength);
142
+ const newMetadataArray = _1.arrayUtils.concatArrays(metadataVersion, newMetadataXmlSize, newMetadataXml, endBuffer);
143
+ return newMetadataArray;
144
+ };
145
+ exports.editSingleQueryMetadata = editSingleQueryMetadata;
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT license.
4
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
5
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
6
+ return new (P || (P = Promise))(function (resolve, reject) {
7
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
8
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
9
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
10
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
11
+ });
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ const constants_1 = require("./constants");
15
+ const generators_1 = require("../generators");
16
+ const buffer_1 = require("buffer");
17
+ const getBase64 = (zip) => __awaiter(void 0, void 0, void 0, function* () {
18
+ const mashup = yield getDataMashupFile(zip);
19
+ return mashup.value;
20
+ });
21
+ const setBase64 = (zip, base64) => __awaiter(void 0, void 0, void 0, function* () {
22
+ const newXml = (0, generators_1.generateMashupXMLTemplate)(base64);
23
+ const encoded = buffer_1.Buffer.from(constants_1.BOM + newXml, "ucs2");
24
+ const mashup = yield getDataMashupFile(zip);
25
+ zip.file(mashup === null || mashup === void 0 ? void 0 : mashup.path, encoded);
26
+ });
27
+ const getDataMashupFile = (zip) => __awaiter(void 0, void 0, void 0, function* () {
28
+ let mashup;
29
+ for (const url of constants_1.URLS.PQ) {
30
+ const item = yield getCustomXmlFile(zip, url);
31
+ if (item.found) {
32
+ mashup = item;
33
+ break;
34
+ }
35
+ }
36
+ if (!mashup) {
37
+ throw new Error("DataMashup XML is not found");
38
+ }
39
+ return mashup;
40
+ });
41
+ const getCustomXmlFile = (zip, url, encoding = "utf16le") => __awaiter(void 0, void 0, void 0, function* () {
42
+ var _a, _b;
43
+ const parser = new DOMParser();
44
+ const itemsArray = yield zip.file(/customXml\/item\d.xml/);
45
+ if (!itemsArray || itemsArray.length === 0) {
46
+ throw new Error("No customXml files were found!");
47
+ }
48
+ let found = false;
49
+ let path;
50
+ let xmlString;
51
+ let value;
52
+ for (let i = 1; i <= itemsArray.length; i++) {
53
+ path = (0, generators_1.generateCustomXmlFilePath)(i);
54
+ const xmlValue = yield ((_a = zip.file(path)) === null || _a === void 0 ? void 0 : _a.async("uint8array"));
55
+ if (xmlValue === undefined) {
56
+ break;
57
+ }
58
+ xmlString = buffer_1.Buffer.from(xmlValue)
59
+ .toString(encoding)
60
+ .replace(/^\ufeff/, "");
61
+ const doc = parser.parseFromString(xmlString, "text/xml");
62
+ found = ((_b = doc === null || doc === void 0 ? void 0 : doc.documentElement) === null || _b === void 0 ? void 0 : _b.namespaceURI) === url;
63
+ if (found) {
64
+ value = doc.documentElement.innerHTML;
65
+ break;
66
+ }
67
+ }
68
+ return { found, path: path, xmlString: xmlString, value };
69
+ });
70
+ const queryNameHasInvalidChars = (queryName) => {
71
+ const invalidQueryNameChars = ['"', "."];
72
+ // Control characters as defined in Unicode
73
+ for (let c = 0; c <= 0x001f; ++c) {
74
+ invalidQueryNameChars.push(String.fromCharCode(c));
75
+ }
76
+ for (let c = 0x007f; c <= 0x009f; ++c) {
77
+ invalidQueryNameChars.push(String.fromCharCode(c));
78
+ }
79
+ return queryName.split("").some((ch) => invalidQueryNameChars.indexOf(ch) !== -1);
80
+ };
81
+ const validateQueryName = (queryName) => {
82
+ if (queryName) {
83
+ if (queryName.length > constants_1.maxQueryLength) {
84
+ throw new Error(constants_1.QueryNameMaxLengthErr);
85
+ }
86
+ if (queryNameHasInvalidChars(queryName)) {
87
+ throw new Error(constants_1.QueryNameInvalidCharsErr);
88
+ }
89
+ }
90
+ if (!queryName.trim()) {
91
+ throw new Error(constants_1.EmptyQueryNameErr);
92
+ }
93
+ };
94
+ exports.default = {
95
+ getBase64,
96
+ setBase64,
97
+ getCustomXmlFile,
98
+ getDataMashupFile,
99
+ validateQueryName,
100
+ };
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT license.
4
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
5
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
6
+ return new (P || (P = Promise))(function (resolve, reject) {
7
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
8
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
9
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
10
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
11
+ });
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ const constants_1 = require("./constants");
18
+ const documentUtils_1 = __importDefault(require("./documentUtils"));
19
+ const uuid_1 = require("uuid");
20
+ const updateTableInitialDataIfNeeded = (zip, tableData, updateQueryTable) => __awaiter(void 0, void 0, void 0, function* () {
21
+ var _a, _b, _c, _d;
22
+ if (!tableData) {
23
+ return;
24
+ }
25
+ const sheetsXmlString = yield ((_a = zip.file(constants_1.sheetsXmlPath)) === null || _a === void 0 ? void 0 : _a.async(constants_1.textResultType));
26
+ if (sheetsXmlString === undefined) {
27
+ throw new Error(constants_1.sheetsNotFoundErr);
28
+ }
29
+ const newSheet = updateSheetsInitialData(sheetsXmlString, tableData);
30
+ zip.file(constants_1.sheetsXmlPath, newSheet);
31
+ if (updateQueryTable) {
32
+ const queryTableXmlString = yield ((_b = zip.file(constants_1.queryTableXmlPath)) === null || _b === void 0 ? void 0 : _b.async(constants_1.textResultType));
33
+ if (queryTableXmlString === undefined) {
34
+ throw new Error(constants_1.queryTableNotFoundErr);
35
+ }
36
+ const newQueryTable = yield updateQueryTablesInitialData(queryTableXmlString, tableData);
37
+ zip.file(constants_1.queryTableXmlPath, newQueryTable);
38
+ // update defined name
39
+ const workbookXmlString = yield ((_c = zip.file(constants_1.workbookXmlPath)) === null || _c === void 0 ? void 0 : _c.async(constants_1.textResultType));
40
+ if (workbookXmlString === undefined) {
41
+ throw new Error(constants_1.sheetsNotFoundErr);
42
+ }
43
+ const newWorkbook = updateWorkbookInitialData(workbookXmlString, tableData);
44
+ zip.file(constants_1.workbookXmlPath, newWorkbook);
45
+ }
46
+ const tableXmlString = yield ((_d = zip.file(constants_1.tableXmlPath)) === null || _d === void 0 ? void 0 : _d.async(constants_1.textResultType));
47
+ if (tableXmlString === undefined) {
48
+ throw new Error(constants_1.tableNotFoundErr);
49
+ }
50
+ const newTable = updateTablesInitialData(tableXmlString, tableData, updateQueryTable);
51
+ zip.file(constants_1.tableXmlPath, newTable);
52
+ });
53
+ const updateTablesInitialData = (tableXmlString, tableData, updateQueryTable = false) => {
54
+ const parser = new DOMParser();
55
+ const serializer = new XMLSerializer();
56
+ const tableDoc = parser.parseFromString(tableXmlString, constants_1.xmlTextResultType);
57
+ const tableColumns = tableDoc.getElementsByTagName(constants_1.element.tableColumns)[0];
58
+ tableColumns.textContent = "";
59
+ tableData.columnNames.forEach((column, columnIndex) => {
60
+ const tableColumn = tableDoc.createElementNS(tableDoc.documentElement.namespaceURI, constants_1.element.tableColumn);
61
+ tableColumn.setAttribute(constants_1.elementAttributes.id, (columnIndex + 1).toString());
62
+ tableColumn.setAttribute(constants_1.elementAttributes.name, column);
63
+ tableColumns.appendChild(tableColumn);
64
+ tableColumn.setAttribute(constants_1.elementAttributes.xr3uid, "{" + (0, uuid_1.v4)().toUpperCase() + "}");
65
+ if (updateQueryTable) {
66
+ tableColumn.setAttribute(constants_1.elementAttributes.uniqueName, (columnIndex + 1).toString());
67
+ tableColumn.setAttribute(constants_1.elementAttributes.queryTableFieldId, (columnIndex + 1).toString());
68
+ }
69
+ });
70
+ tableColumns.setAttribute(constants_1.elementAttributes.count, tableData.columnNames.length.toString());
71
+ tableDoc
72
+ .getElementsByTagName(constants_1.element.table)[0]
73
+ .setAttribute(constants_1.elementAttributes.reference, `A1:${documentUtils_1.default.getCellReferenceRelative(tableData.columnNames.length - 1, tableData.rows.length + 1)}`);
74
+ tableDoc
75
+ .getElementsByTagName(constants_1.element.autoFilter)[0]
76
+ .setAttribute(constants_1.elementAttributes.reference, `A1:${documentUtils_1.default.getCellReferenceRelative(tableData.columnNames.length - 1, tableData.rows.length + 1)}`);
77
+ return serializer.serializeToString(tableDoc);
78
+ };
79
+ const updateWorkbookInitialData = (workbookXmlString, tableData) => {
80
+ const newParser = new DOMParser();
81
+ const newSerializer = new XMLSerializer();
82
+ const workbookDoc = newParser.parseFromString(workbookXmlString, constants_1.xmlTextResultType);
83
+ const definedName = workbookDoc.getElementsByTagName(constants_1.element.definedName)[0];
84
+ definedName.textContent =
85
+ constants_1.defaults.sheetName + `!$A$1:${documentUtils_1.default.getCellReferenceAbsolute(tableData.columnNames.length - 1, tableData.rows.length + 1)}`;
86
+ return newSerializer.serializeToString(workbookDoc);
87
+ };
88
+ const updateQueryTablesInitialData = (queryTableXmlString, tableData) => {
89
+ const parser = new DOMParser();
90
+ const serializer = new XMLSerializer();
91
+ const queryTableDoc = parser.parseFromString(queryTableXmlString, constants_1.xmlTextResultType);
92
+ const queryTableFields = queryTableDoc.getElementsByTagName(constants_1.element.queryTableFields)[0];
93
+ queryTableFields.textContent = "";
94
+ tableData.columnNames.forEach((column, columnIndex) => {
95
+ const queryTableField = queryTableDoc.createElementNS(queryTableDoc.documentElement.namespaceURI, constants_1.element.queryTableField);
96
+ queryTableField.setAttribute(constants_1.elementAttributes.id, (columnIndex + 1).toString());
97
+ queryTableField.setAttribute(constants_1.elementAttributes.name, column);
98
+ queryTableField.setAttribute(constants_1.elementAttributes.tableColumnId, (columnIndex + 1).toString());
99
+ queryTableFields.appendChild(queryTableField);
100
+ });
101
+ queryTableFields.setAttribute(constants_1.elementAttributes.count, tableData.columnNames.length.toString());
102
+ queryTableDoc.getElementsByTagName(constants_1.element.queryTableRefresh)[0].setAttribute(constants_1.elementAttributes.nextId, (tableData.columnNames.length + 1).toString());
103
+ return serializer.serializeToString(queryTableDoc);
104
+ };
105
+ const updateSheetsInitialData = (sheetsXmlString, tableData) => {
106
+ const parser = new DOMParser();
107
+ const serializer = new XMLSerializer();
108
+ const sheetsDoc = parser.parseFromString(sheetsXmlString, constants_1.xmlTextResultType);
109
+ const sheetData = sheetsDoc.getElementsByTagName(constants_1.element.sheetData)[0];
110
+ sheetData.textContent = "";
111
+ let rowIndex = 0;
112
+ const columnRow = sheetsDoc.createElementNS(sheetsDoc.documentElement.namespaceURI, constants_1.element.row);
113
+ columnRow.setAttribute(constants_1.elementAttributes.row, (rowIndex + 1).toString());
114
+ columnRow.setAttribute(constants_1.elementAttributes.spans, "1:" + tableData.columnNames.length);
115
+ columnRow.setAttribute(constants_1.elementAttributes.x14acDyDescent, "0.3");
116
+ tableData.columnNames.forEach((col, colIndex) => {
117
+ columnRow.appendChild(documentUtils_1.default.createCell(sheetsDoc, colIndex, rowIndex, col));
118
+ });
119
+ sheetData.appendChild(columnRow);
120
+ rowIndex++;
121
+ tableData.rows.forEach((row) => {
122
+ const newRow = sheetsDoc.createElementNS(sheetsDoc.documentElement.namespaceURI, constants_1.element.row);
123
+ newRow.setAttribute(constants_1.elementAttributes.row, (rowIndex + 1).toString());
124
+ newRow.setAttribute(constants_1.elementAttributes.spans, "1:" + row.length);
125
+ newRow.setAttribute(constants_1.elementAttributes.x14acDyDescent, "0.3");
126
+ row.forEach((cellContent, colIndex) => {
127
+ newRow.appendChild(documentUtils_1.default.createCell(sheetsDoc, colIndex, rowIndex, cellContent));
128
+ });
129
+ sheetData.appendChild(newRow);
130
+ rowIndex++;
131
+ });
132
+ sheetsDoc
133
+ .getElementsByTagName(constants_1.element.dimension)[0]
134
+ .setAttribute(constants_1.elementAttributes.reference, documentUtils_1.default.getTableReference(tableData.rows[0].length - 1, tableData.rows.length));
135
+ return serializer.serializeToString(sheetsDoc);
136
+ };
137
+ exports.default = {
138
+ updateTableInitialDataIfNeeded,
139
+ updateSheetsInitialData,
140
+ updateWorkbookInitialData,
141
+ updateTablesInitialData,
142
+ updateQueryTablesInitialData,
143
+ };
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT license.
4
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
5
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
6
+ return new (P || (P = Promise))(function (resolve, reject) {
7
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
8
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
9
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
10
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
11
+ });
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ const types_1 = require("../types");
18
+ const constants_1 = require("./constants");
19
+ const documentUtils_1 = __importDefault(require("./documentUtils"));
20
+ const updateDocProps = (zip, docProps = {}) => __awaiter(void 0, void 0, void 0, function* () {
21
+ const { doc, properties } = yield documentUtils_1.default.getDocPropsProperties(zip);
22
+ //set auto updated elements
23
+ const docPropsAutoUpdatedElementsArr = Object.keys(types_1.DocPropsAutoUpdatedElements);
24
+ const nowTime = new Date().toISOString();
25
+ docPropsAutoUpdatedElementsArr.forEach((tag) => {
26
+ documentUtils_1.default.createOrUpdateProperty(doc, properties, types_1.DocPropsAutoUpdatedElements[tag], nowTime);
27
+ });
28
+ //set modifiable elements
29
+ const docPropsModifiableElementsArr = Object.keys(types_1.DocPropsModifiableElements);
30
+ docPropsModifiableElementsArr
31
+ .map((key) => ({
32
+ name: types_1.DocPropsModifiableElements[key],
33
+ value: docProps[key],
34
+ }))
35
+ .forEach((kvp) => {
36
+ documentUtils_1.default.createOrUpdateProperty(doc, properties, kvp.name, kvp.value);
37
+ });
38
+ const serializer = new XMLSerializer();
39
+ const newDoc = serializer.serializeToString(doc);
40
+ zip.file(constants_1.docPropsCoreXmlPath, newDoc);
41
+ });
42
+ const updateConnections = (connectionsXmlString, queryName, refreshOnOpen) => {
43
+ var _a, _b, _c;
44
+ const parser = new DOMParser();
45
+ const serializer = new XMLSerializer();
46
+ const refreshOnLoadValue = refreshOnOpen ? constants_1.trueValue : constants_1.falseValue;
47
+ const connectionsDoc = parser.parseFromString(connectionsXmlString, constants_1.xmlTextResultType);
48
+ const connectionsProperties = connectionsDoc.getElementsByTagName(constants_1.element.databaseProperties);
49
+ const dbPr = connectionsProperties[0];
50
+ dbPr.setAttribute(constants_1.elementAttributes.refreshOnLoad, refreshOnLoadValue);
51
+ // Update query details to match queryName
52
+ (_a = dbPr.parentElement) === null || _a === void 0 ? void 0 : _a.setAttribute(constants_1.elementAttributes.name, constants_1.elementAttributesValues.connectionName(queryName));
53
+ (_b = dbPr.parentElement) === null || _b === void 0 ? void 0 : _b.setAttribute(constants_1.elementAttributes.description, constants_1.elementAttributesValues.connectionDescription(queryName));
54
+ dbPr.setAttribute(constants_1.elementAttributes.connection, constants_1.elementAttributesValues.connection(queryName));
55
+ dbPr.setAttribute(constants_1.elementAttributes.command, constants_1.elementAttributesValues.connectionCommand(queryName));
56
+ const connectionId = (_c = dbPr.parentElement) === null || _c === void 0 ? void 0 : _c.getAttribute(constants_1.elementAttributes.id);
57
+ const connectionXmlFileString = serializer.serializeToString(connectionsDoc);
58
+ if (connectionId === null) {
59
+ throw new Error(constants_1.connectionsNotFoundErr);
60
+ }
61
+ return { connectionId, connectionXmlFileString };
62
+ };
63
+ const updateSharedStrings = (sharedStringsXmlString, queryName) => {
64
+ const parser = new DOMParser();
65
+ const serializer = new XMLSerializer();
66
+ const sharedStringsDoc = parser.parseFromString(sharedStringsXmlString, constants_1.xmlTextResultType);
67
+ const sharedStringsTable = sharedStringsDoc.getElementsByTagName(constants_1.element.sharedStringTable)[0];
68
+ if (!sharedStringsTable) {
69
+ throw new Error(constants_1.sharedStringsNotFoundErr);
70
+ }
71
+ const textElementCollection = sharedStringsDoc.getElementsByTagName(constants_1.element.text);
72
+ let textElement = null;
73
+ let sharedStringIndex = textElementCollection.length;
74
+ if (textElementCollection && textElementCollection.length) {
75
+ for (let i = 0; i < textElementCollection.length; i++) {
76
+ if (textElementCollection[i].innerHTML === queryName) {
77
+ textElement = textElementCollection[i];
78
+ sharedStringIndex = i + 1;
79
+ break;
80
+ }
81
+ }
82
+ }
83
+ if (textElement === null) {
84
+ if (sharedStringsDoc.documentElement.namespaceURI) {
85
+ textElement = sharedStringsDoc.createElementNS(sharedStringsDoc.documentElement.namespaceURI, constants_1.element.text);
86
+ textElement.textContent = queryName;
87
+ const siElement = sharedStringsDoc.createElementNS(sharedStringsDoc.documentElement.namespaceURI, constants_1.element.sharedStringItem);
88
+ siElement.appendChild(textElement);
89
+ sharedStringsDoc.getElementsByTagName(constants_1.element.sharedStringTable)[0].appendChild(siElement);
90
+ }
91
+ const value = sharedStringsTable.getAttribute(constants_1.elementAttributes.count);
92
+ if (value) {
93
+ sharedStringsTable.setAttribute(constants_1.elementAttributes.count, (parseInt(value) + 1).toString());
94
+ }
95
+ const uniqueValue = sharedStringsTable.getAttribute(constants_1.elementAttributes.uniqueCount);
96
+ if (uniqueValue) {
97
+ sharedStringsTable.setAttribute(constants_1.elementAttributes.uniqueCount, (parseInt(uniqueValue) + 1).toString());
98
+ }
99
+ }
100
+ const newSharedStrings = serializer.serializeToString(sharedStringsDoc);
101
+ return { sharedStringIndex, newSharedStrings };
102
+ };
103
+ const updateWorksheet = (sheetsXmlString, sharedStringIndex) => {
104
+ const parser = new DOMParser();
105
+ const serializer = new XMLSerializer();
106
+ const sheetsDoc = parser.parseFromString(sheetsXmlString, constants_1.xmlTextResultType);
107
+ sheetsDoc.getElementsByTagName(constants_1.element.cellValue)[0].innerHTML = sharedStringIndex.toString();
108
+ const newSheet = serializer.serializeToString(sheetsDoc);
109
+ return newSheet;
110
+ };
111
+ const updatePivotTablesandQueryTables = (zip, queryName, refreshOnOpen, connectionId) => __awaiter(void 0, void 0, void 0, function* () {
112
+ var _a, _b;
113
+ // Find Query Table
114
+ let found = false;
115
+ const queryTablePromises = [];
116
+ (_a = zip.folder(constants_1.queryTablesPath)) === null || _a === void 0 ? void 0 : _a.forEach((relativePath, queryTableFile) => __awaiter(void 0, void 0, void 0, function* () {
117
+ queryTablePromises.push((() => {
118
+ return queryTableFile.async(constants_1.textResultType).then((queryTableString) => {
119
+ return {
120
+ path: relativePath,
121
+ queryTableXmlString: queryTableString,
122
+ };
123
+ });
124
+ })());
125
+ }));
126
+ (yield Promise.all(queryTablePromises)).forEach(({ path, queryTableXmlString }) => {
127
+ const { isQueryTableUpdated, newQueryTable } = updateQueryTable(queryTableXmlString, connectionId, refreshOnOpen);
128
+ zip.file(constants_1.queryTablesPath + path, newQueryTable);
129
+ if (isQueryTableUpdated) {
130
+ found = true;
131
+ }
132
+ });
133
+ if (found) {
134
+ return;
135
+ }
136
+ // Find Pivot Table
137
+ const pivotCachePromises = [];
138
+ (_b = zip.folder(constants_1.pivotCachesPath)) === null || _b === void 0 ? void 0 : _b.forEach((relativePath, pivotCacheFile) => __awaiter(void 0, void 0, void 0, function* () {
139
+ if (relativePath.startsWith(constants_1.pivotCachesPathPrefix)) {
140
+ pivotCachePromises.push((() => {
141
+ return pivotCacheFile.async(constants_1.textResultType).then((pivotCacheString) => {
142
+ return {
143
+ path: relativePath,
144
+ pivotCacheXmlString: pivotCacheString,
145
+ };
146
+ });
147
+ })());
148
+ }
149
+ }));
150
+ (yield Promise.all(pivotCachePromises)).forEach(({ path, pivotCacheXmlString }) => {
151
+ const { isPivotTableUpdated, newPivotTable } = updatePivotTable(pivotCacheXmlString, connectionId, refreshOnOpen);
152
+ zip.file(constants_1.pivotCachesPath + path, newPivotTable);
153
+ if (isPivotTableUpdated) {
154
+ found = true;
155
+ }
156
+ });
157
+ if (!found) {
158
+ throw new Error(constants_1.queryAndPivotTableNotFoundErr);
159
+ }
160
+ });
161
+ const updateQueryTable = (tableXmlString, connectionId, refreshOnOpen) => {
162
+ const refreshOnLoadValue = refreshOnOpen ? constants_1.trueValue : constants_1.falseValue;
163
+ let isQueryTableUpdated = false;
164
+ const parser = new DOMParser();
165
+ const serializer = new XMLSerializer();
166
+ const queryTableDoc = parser.parseFromString(tableXmlString, constants_1.xmlTextResultType);
167
+ const queryTable = queryTableDoc.getElementsByTagName(constants_1.element.queryTable)[0];
168
+ let newQueryTable = constants_1.emptyValue;
169
+ if (queryTable.getAttribute(constants_1.elementAttributes.connectionId) == connectionId) {
170
+ queryTable.setAttribute(constants_1.elementAttributes.refreshOnLoad, refreshOnLoadValue);
171
+ newQueryTable = serializer.serializeToString(queryTableDoc);
172
+ isQueryTableUpdated = true;
173
+ }
174
+ return { isQueryTableUpdated, newQueryTable };
175
+ };
176
+ const updatePivotTable = (tableXmlString, connectionId, refreshOnOpen) => {
177
+ const refreshOnLoadValue = refreshOnOpen ? constants_1.trueValue : constants_1.falseValue;
178
+ let isPivotTableUpdated = false;
179
+ const parser = new DOMParser();
180
+ const serializer = new XMLSerializer();
181
+ const pivotCacheDoc = parser.parseFromString(tableXmlString, constants_1.xmlTextResultType);
182
+ let cacheSource = pivotCacheDoc.getElementsByTagName(constants_1.element.cacheSource)[0];
183
+ let newPivotTable = constants_1.emptyValue;
184
+ if (cacheSource.getAttribute(constants_1.elementAttributes.connectionId) == connectionId) {
185
+ cacheSource = cacheSource.parentElement;
186
+ cacheSource.setAttribute(constants_1.elementAttributes.refreshOnLoad, refreshOnLoadValue);
187
+ newPivotTable = serializer.serializeToString(pivotCacheDoc);
188
+ isPivotTableUpdated = true;
189
+ }
190
+ return { isPivotTableUpdated, newPivotTable };
191
+ };
192
+ exports.default = {
193
+ updateDocProps,
194
+ updateConnections,
195
+ updateSharedStrings,
196
+ updateWorksheet,
197
+ updatePivotTablesandQueryTables,
198
+ updateQueryTable,
199
+ updatePivotTable,
200
+ };
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT license.
4
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
5
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
6
+ return new (P || (P = Promise))(function (resolve, reject) {
7
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
8
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
9
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
10
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
11
+ });
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ const constants_1 = require("./constants");
18
+ const mashupDocumentParser_1 = require("./mashupDocumentParser");
19
+ const pqUtils_1 = __importDefault(require("./pqUtils"));
20
+ const xmlInnerPartsUtils_1 = __importDefault(require("./xmlInnerPartsUtils"));
21
+ const tableUtils_1 = __importDefault(require("./tableUtils"));
22
+ const updateWorkbookInitialDataIfNeeded = (zip, docProps, tableData, updateQueryTable = false) => __awaiter(void 0, void 0, void 0, function* () {
23
+ yield xmlInnerPartsUtils_1.default.updateDocProps(zip, docProps);
24
+ yield tableUtils_1.default.updateTableInitialDataIfNeeded(zip, tableData, updateQueryTable);
25
+ });
26
+ const updateWorkbookPowerQueryDocument = (zip, queryName, queryMashupDoc) => __awaiter(void 0, void 0, void 0, function* () {
27
+ const old_base64 = yield pqUtils_1.default.getBase64(zip);
28
+ if (!old_base64) {
29
+ throw new Error(constants_1.base64NotFoundErr);
30
+ }
31
+ const new_base64 = yield (0, mashupDocumentParser_1.replaceSingleQuery)(old_base64, queryName, queryMashupDoc);
32
+ yield pqUtils_1.default.setBase64(zip, new_base64);
33
+ });
34
+ const updateWorkbookSingleQueryAttributes = (zip, queryName, refreshOnOpen) => __awaiter(void 0, void 0, void 0, function* () {
35
+ var _a, _b, _c;
36
+ // Update connections
37
+ const connectionsXmlString = yield ((_a = zip.file(constants_1.connectionsXmlPath)) === null || _a === void 0 ? void 0 : _a.async(constants_1.textResultType));
38
+ if (connectionsXmlString === undefined) {
39
+ throw new Error(constants_1.connectionsNotFoundErr);
40
+ }
41
+ const { connectionId, connectionXmlFileString } = xmlInnerPartsUtils_1.default.updateConnections(connectionsXmlString, queryName, refreshOnOpen);
42
+ zip.file(constants_1.connectionsXmlPath, connectionXmlFileString);
43
+ // Update sharedStrings
44
+ const sharedStringsXmlString = yield ((_b = zip.file(constants_1.sharedStringsXmlPath)) === null || _b === void 0 ? void 0 : _b.async(constants_1.textResultType));
45
+ if (sharedStringsXmlString === undefined) {
46
+ throw new Error(constants_1.sharedStringsNotFoundErr);
47
+ }
48
+ const { sharedStringIndex, newSharedStrings } = xmlInnerPartsUtils_1.default.updateSharedStrings(sharedStringsXmlString, queryName);
49
+ zip.file(constants_1.sharedStringsXmlPath, newSharedStrings);
50
+ // Update sheet
51
+ const sheetsXmlString = yield ((_c = zip.file(constants_1.sheetsXmlPath)) === null || _c === void 0 ? void 0 : _c.async(constants_1.textResultType));
52
+ if (sheetsXmlString === undefined) {
53
+ throw new Error(constants_1.sheetsNotFoundErr);
54
+ }
55
+ const worksheetString = xmlInnerPartsUtils_1.default.updateWorksheet(sheetsXmlString, sharedStringIndex.toString());
56
+ zip.file(constants_1.sheetsXmlPath, worksheetString);
57
+ // Update tables
58
+ yield xmlInnerPartsUtils_1.default.updatePivotTablesandQueryTables(zip, queryName, refreshOnOpen, connectionId);
59
+ });
60
+ exports.default = {
61
+ updateWorkbookInitialDataIfNeeded,
62
+ updateWorkbookPowerQueryDocument,
63
+ updateWorkbookSingleQueryAttributes,
64
+ };