@microsoft/connected-workbooks 2.1.24-beta → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -13
- package/dist/generators.js +1 -1
- package/dist/{GridParser.js → gridParser.js} +18 -8
- package/dist/gridUtils.js +58 -0
- package/dist/index.d.ts +2 -2
- package/dist/src/generators.js +14 -0
- package/dist/src/types.js +28 -0
- package/dist/src/utils/arrayUtils.js +46 -0
- package/dist/src/utils/constants.js +145 -0
- package/dist/src/utils/documentUtils.js +102 -0
- package/dist/src/utils/gridUtils.js +103 -0
- package/dist/src/utils/htmlUtils.js +19 -0
- package/dist/src/utils/index.js +24 -0
- package/dist/src/utils/mashupDocumentParser.js +145 -0
- package/dist/src/utils/pqUtils.js +100 -0
- package/dist/src/utils/tableUtils.js +143 -0
- package/dist/src/utils/xmlInnerPartsUtils.js +227 -0
- package/dist/src/utils/xmlPartsUtils.js +68 -0
- package/dist/src/workbookTemplate.js +7 -0
- package/dist/tests/arrayUtils.test.js +65 -0
- package/dist/tests/documentUtils.test.js +35 -0
- package/dist/tests/gridUtils.test.js +168 -0
- package/dist/tests/htmlUtils.test.js +109 -0
- package/dist/tests/mashupDocumentParser.test.js +59 -0
- package/dist/tests/mocks/PqMock.js +7 -0
- package/dist/tests/mocks/index.js +24 -0
- package/dist/tests/mocks/section1mSimpleQueryMock.js +18 -0
- package/dist/tests/mocks/xmlMocks.js +12 -0
- package/dist/tests/tableUtils.test.js +63 -0
- package/dist/tests/workbookQueryTemplate.test.js +64 -0
- package/dist/tests/workbookTableTemplate.test.js +54 -0
- package/dist/tests/xmlInnerPartsUtils.test.js +51 -0
- package/dist/types.d.ts +4 -1
- package/dist/utils/constants.js +20 -9
- package/dist/utils/documentUtils.js +9 -5
- package/dist/utils/gridUtils.js +103 -0
- package/dist/utils/htmlUtils.js +3 -3
- package/dist/utils/index.js +5 -1
- package/dist/utils/mashupDocumentParser.js +6 -24
- package/dist/utils/pqUtils.js +7 -4
- package/dist/utils/tableUtils.js +18 -19
- package/dist/utils/xmlInnerPartsUtils.js +38 -9
- package/dist/utils/xmlPartsUtils.js +12 -6
- package/dist/workbookManager.d.ts +3 -3
- package/dist/workbookManager.js +17 -22
- package/package.json +5 -3
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation.
|
|
3
|
+
// Licensed under the MIT license.
|
|
2
4
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
5
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
6
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -37,7 +39,33 @@ const updateDocProps = (zip, docProps = {}) => __awaiter(void 0, void 0, void 0,
|
|
|
37
39
|
const newDoc = serializer.serializeToString(doc);
|
|
38
40
|
zip.file(constants_1.docPropsCoreXmlPath, newDoc);
|
|
39
41
|
});
|
|
40
|
-
const
|
|
42
|
+
const clearLabelInfo = (zip) => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
|
+
var _a, _b, _c, _d;
|
|
44
|
+
// remove docMetadata folder that contains only LabelInfo.xml in template file.
|
|
45
|
+
zip.remove(constants_1.docMetadataXmlPath);
|
|
46
|
+
// fix rels
|
|
47
|
+
const relsString = yield ((_a = zip.file(constants_1.relsXmlPath)) === null || _a === void 0 ? void 0 : _a.async(constants_1.textResultType));
|
|
48
|
+
if (relsString === undefined) {
|
|
49
|
+
throw new Error(constants_1.relsNotFoundErr);
|
|
50
|
+
}
|
|
51
|
+
const parser = new DOMParser();
|
|
52
|
+
const doc = parser.parseFromString(relsString, constants_1.xmlTextResultType);
|
|
53
|
+
const relationships = doc.querySelector("Relationships");
|
|
54
|
+
if (relationships === null) {
|
|
55
|
+
throw new Error(constants_1.unexpectedErr);
|
|
56
|
+
}
|
|
57
|
+
const element = relationships.querySelector('Relationship[Target="docMetadata/LabelInfo.xml"]');
|
|
58
|
+
if (element) {
|
|
59
|
+
relationships.removeChild(element);
|
|
60
|
+
}
|
|
61
|
+
(_b = relationships.querySelector('Relationship[Target="xl/workbook.xml"]')) === null || _b === void 0 ? void 0 : _b.setAttribute("Id", "rId1");
|
|
62
|
+
(_c = relationships.querySelector('Relationship[Target="docProps/core.xml"]')) === null || _c === void 0 ? void 0 : _c.setAttribute("Id", "rId2");
|
|
63
|
+
(_d = relationships.querySelector('Relationship[Target="docProps/app.xml"]')) === null || _d === void 0 ? void 0 : _d.setAttribute("Id", "rId3");
|
|
64
|
+
const serializer = new XMLSerializer();
|
|
65
|
+
const newDoc = serializer.serializeToString(doc);
|
|
66
|
+
zip.file(constants_1.relsXmlPath, newDoc);
|
|
67
|
+
});
|
|
68
|
+
const updateConnections = (connectionsXmlString, queryName, refreshOnOpen) => {
|
|
41
69
|
var _a, _b, _c;
|
|
42
70
|
const parser = new DOMParser();
|
|
43
71
|
const serializer = new XMLSerializer();
|
|
@@ -57,8 +85,8 @@ const updateConnections = (connectionsXmlString, queryName, refreshOnOpen) => __
|
|
|
57
85
|
throw new Error(constants_1.connectionsNotFoundErr);
|
|
58
86
|
}
|
|
59
87
|
return { connectionId, connectionXmlFileString };
|
|
60
|
-
}
|
|
61
|
-
const updateSharedStrings = (sharedStringsXmlString, queryName) =>
|
|
88
|
+
};
|
|
89
|
+
const updateSharedStrings = (sharedStringsXmlString, queryName) => {
|
|
62
90
|
const parser = new DOMParser();
|
|
63
91
|
const serializer = new XMLSerializer();
|
|
64
92
|
const sharedStringsDoc = parser.parseFromString(sharedStringsXmlString, constants_1.xmlTextResultType);
|
|
@@ -97,21 +125,21 @@ const updateSharedStrings = (sharedStringsXmlString, queryName) => __awaiter(voi
|
|
|
97
125
|
}
|
|
98
126
|
const newSharedStrings = serializer.serializeToString(sharedStringsDoc);
|
|
99
127
|
return { sharedStringIndex, newSharedStrings };
|
|
100
|
-
}
|
|
101
|
-
const updateWorksheet = (sheetsXmlString, sharedStringIndex) =>
|
|
128
|
+
};
|
|
129
|
+
const updateWorksheet = (sheetsXmlString, sharedStringIndex) => {
|
|
102
130
|
const parser = new DOMParser();
|
|
103
131
|
const serializer = new XMLSerializer();
|
|
104
132
|
const sheetsDoc = parser.parseFromString(sheetsXmlString, constants_1.xmlTextResultType);
|
|
105
133
|
sheetsDoc.getElementsByTagName(constants_1.element.cellValue)[0].innerHTML = sharedStringIndex.toString();
|
|
106
134
|
const newSheet = serializer.serializeToString(sheetsDoc);
|
|
107
135
|
return newSheet;
|
|
108
|
-
}
|
|
136
|
+
};
|
|
109
137
|
const updatePivotTablesandQueryTables = (zip, queryName, refreshOnOpen, connectionId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
110
|
-
var
|
|
138
|
+
var _e, _f;
|
|
111
139
|
// Find Query Table
|
|
112
140
|
let found = false;
|
|
113
141
|
const queryTablePromises = [];
|
|
114
|
-
(
|
|
142
|
+
(_e = zip.folder(constants_1.queryTablesPath)) === null || _e === void 0 ? void 0 : _e.forEach((relativePath, queryTableFile) => __awaiter(void 0, void 0, void 0, function* () {
|
|
115
143
|
queryTablePromises.push((() => {
|
|
116
144
|
return queryTableFile.async(constants_1.textResultType).then((queryTableString) => {
|
|
117
145
|
return {
|
|
@@ -133,7 +161,7 @@ const updatePivotTablesandQueryTables = (zip, queryName, refreshOnOpen, connecti
|
|
|
133
161
|
}
|
|
134
162
|
// Find Pivot Table
|
|
135
163
|
const pivotCachePromises = [];
|
|
136
|
-
(
|
|
164
|
+
(_f = zip.folder(constants_1.pivotCachesPath)) === null || _f === void 0 ? void 0 : _f.forEach((relativePath, pivotCacheFile) => __awaiter(void 0, void 0, void 0, function* () {
|
|
137
165
|
if (relativePath.startsWith(constants_1.pivotCachesPathPrefix)) {
|
|
138
166
|
pivotCachePromises.push((() => {
|
|
139
167
|
return pivotCacheFile.async(constants_1.textResultType).then((pivotCacheString) => {
|
|
@@ -189,6 +217,7 @@ const updatePivotTable = (tableXmlString, connectionId, refreshOnOpen) => {
|
|
|
189
217
|
};
|
|
190
218
|
exports.default = {
|
|
191
219
|
updateDocProps,
|
|
220
|
+
clearLabelInfo,
|
|
192
221
|
updateConnections,
|
|
193
222
|
updateSharedStrings,
|
|
194
223
|
updateWorksheet,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation.
|
|
3
|
+
// Licensed under the MIT license.
|
|
2
4
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
5
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
6
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -17,8 +19,12 @@ const mashupDocumentParser_1 = require("./mashupDocumentParser");
|
|
|
17
19
|
const pqUtils_1 = __importDefault(require("./pqUtils"));
|
|
18
20
|
const xmlInnerPartsUtils_1 = __importDefault(require("./xmlInnerPartsUtils"));
|
|
19
21
|
const tableUtils_1 = __importDefault(require("./tableUtils"));
|
|
20
|
-
const
|
|
21
|
-
yield xmlInnerPartsUtils_1.default.updateDocProps(zip, docProps);
|
|
22
|
+
const updateWorkbookDataAndConfigurations = (zip, fileConfigs, tableData, updateQueryTable = false) => __awaiter(void 0, void 0, void 0, function* () {
|
|
23
|
+
yield xmlInnerPartsUtils_1.default.updateDocProps(zip, fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.docProps);
|
|
24
|
+
if ((fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.templateFile) === undefined) {
|
|
25
|
+
// If we are using our base template, we need to clear label info
|
|
26
|
+
yield xmlInnerPartsUtils_1.default.clearLabelInfo(zip);
|
|
27
|
+
}
|
|
22
28
|
yield tableUtils_1.default.updateTableInitialDataIfNeeded(zip, tableData, updateQueryTable);
|
|
23
29
|
});
|
|
24
30
|
const updateWorkbookPowerQueryDocument = (zip, queryName, queryMashupDoc) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -36,27 +42,27 @@ const updateWorkbookSingleQueryAttributes = (zip, queryName, refreshOnOpen) => _
|
|
|
36
42
|
if (connectionsXmlString === undefined) {
|
|
37
43
|
throw new Error(constants_1.connectionsNotFoundErr);
|
|
38
44
|
}
|
|
39
|
-
const { connectionId, connectionXmlFileString } =
|
|
45
|
+
const { connectionId, connectionXmlFileString } = xmlInnerPartsUtils_1.default.updateConnections(connectionsXmlString, queryName, refreshOnOpen);
|
|
40
46
|
zip.file(constants_1.connectionsXmlPath, connectionXmlFileString);
|
|
41
47
|
// Update sharedStrings
|
|
42
48
|
const sharedStringsXmlString = yield ((_b = zip.file(constants_1.sharedStringsXmlPath)) === null || _b === void 0 ? void 0 : _b.async(constants_1.textResultType));
|
|
43
49
|
if (sharedStringsXmlString === undefined) {
|
|
44
50
|
throw new Error(constants_1.sharedStringsNotFoundErr);
|
|
45
51
|
}
|
|
46
|
-
const { sharedStringIndex, newSharedStrings } =
|
|
52
|
+
const { sharedStringIndex, newSharedStrings } = xmlInnerPartsUtils_1.default.updateSharedStrings(sharedStringsXmlString, queryName);
|
|
47
53
|
zip.file(constants_1.sharedStringsXmlPath, newSharedStrings);
|
|
48
54
|
// Update sheet
|
|
49
55
|
const sheetsXmlString = yield ((_c = zip.file(constants_1.sheetsXmlPath)) === null || _c === void 0 ? void 0 : _c.async(constants_1.textResultType));
|
|
50
56
|
if (sheetsXmlString === undefined) {
|
|
51
57
|
throw new Error(constants_1.sheetsNotFoundErr);
|
|
52
58
|
}
|
|
53
|
-
const worksheetString =
|
|
59
|
+
const worksheetString = xmlInnerPartsUtils_1.default.updateWorksheet(sheetsXmlString, sharedStringIndex.toString());
|
|
54
60
|
zip.file(constants_1.sheetsXmlPath, worksheetString);
|
|
55
61
|
// Update tables
|
|
56
62
|
yield xmlInnerPartsUtils_1.default.updatePivotTablesandQueryTables(zip, queryName, refreshOnOpen, connectionId);
|
|
57
63
|
});
|
|
58
64
|
exports.default = {
|
|
59
|
-
|
|
65
|
+
updateWorkbookDataAndConfigurations,
|
|
60
66
|
updateWorkbookPowerQueryDocument,
|
|
61
67
|
updateWorkbookSingleQueryAttributes,
|
|
62
68
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { QueryInfo, Grid, FileConfigs } from "./types";
|
|
2
2
|
export declare const generateSingleQueryWorkbook: (query: QueryInfo, initialDataGrid?: Grid, fileConfigs?: FileConfigs) => Promise<Blob>;
|
|
3
|
-
export declare const generateTableWorkbookFromHtml: (htmlTable: HTMLTableElement,
|
|
4
|
-
export declare const generateTableWorkbookFromGrid: (grid: Grid,
|
|
3
|
+
export declare const generateTableWorkbookFromHtml: (htmlTable: HTMLTableElement, fileConfigs?: FileConfigs) => Promise<Blob>;
|
|
4
|
+
export declare const generateTableWorkbookFromGrid: (grid: Grid, fileConfigs?: FileConfigs) => Promise<Blob>;
|
|
5
5
|
export declare const downloadWorkbook: (file: Blob, filename: string) => void;
|
package/dist/workbookManager.js
CHANGED
|
@@ -20,8 +20,6 @@ const utils_1 = require("./utils");
|
|
|
20
20
|
const workbookTemplate_1 = require("./workbookTemplate");
|
|
21
21
|
const constants_1 = require("./utils/constants");
|
|
22
22
|
const generators_1 = require("./generators");
|
|
23
|
-
const htmlUtils_1 = require("./utils/htmlUtils");
|
|
24
|
-
const GridParser_1 = require("./GridParser");
|
|
25
23
|
const generateSingleQueryWorkbook = (query, initialDataGrid, fileConfigs) => __awaiter(void 0, void 0, void 0, function* () {
|
|
26
24
|
if (!query.queryMashup) {
|
|
27
25
|
throw new Error(constants_1.emptyQueryMashupErr);
|
|
@@ -34,45 +32,42 @@ const generateSingleQueryWorkbook = (query, initialDataGrid, fileConfigs) => __a
|
|
|
34
32
|
throw new Error(constants_1.templateWithInitialDataErr);
|
|
35
33
|
}
|
|
36
34
|
utils_1.pqUtils.validateQueryName(query.queryName);
|
|
37
|
-
const zip = templateFile === undefined
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const tableData = yield parseInitialDataGrid(initialDataGrid);
|
|
41
|
-
return yield generateSingleQueryWorkbookFromZip(zip, query, fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.docProps, tableData);
|
|
35
|
+
const zip = templateFile === undefined ? yield jszip_1.default.loadAsync(workbookTemplate_1.SIMPLE_QUERY_WORKBOOK_TEMPLATE, { base64: true }) : yield jszip_1.default.loadAsync(templateFile);
|
|
36
|
+
const tableData = initialDataGrid ? utils_1.gridUtils.parseToTableData(initialDataGrid) : undefined;
|
|
37
|
+
return yield generateSingleQueryWorkbookFromZip(zip, query, fileConfigs, tableData);
|
|
42
38
|
});
|
|
43
39
|
exports.generateSingleQueryWorkbook = generateSingleQueryWorkbook;
|
|
44
|
-
const generateTableWorkbookFromHtml = (htmlTable,
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
const generateTableWorkbookFromHtml = (htmlTable, fileConfigs) => __awaiter(void 0, void 0, void 0, function* () {
|
|
41
|
+
if ((fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.templateFile) !== undefined) {
|
|
42
|
+
throw new Error(constants_1.templateFileNotSupportedErr);
|
|
43
|
+
}
|
|
44
|
+
const gridData = utils_1.htmlUtils.extractTableValues(htmlTable);
|
|
45
|
+
return yield (0, exports.generateTableWorkbookFromGrid)({ data: gridData, config: { promoteHeaders: true } }, fileConfigs);
|
|
47
46
|
});
|
|
48
47
|
exports.generateTableWorkbookFromHtml = generateTableWorkbookFromHtml;
|
|
49
|
-
const generateTableWorkbookFromGrid = (grid,
|
|
48
|
+
const generateTableWorkbookFromGrid = (grid, fileConfigs) => __awaiter(void 0, void 0, void 0, function* () {
|
|
49
|
+
if ((fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.templateFile) !== undefined) {
|
|
50
|
+
throw new Error(constants_1.templateFileNotSupportedErr);
|
|
51
|
+
}
|
|
50
52
|
const zip = yield jszip_1.default.loadAsync(workbookTemplate_1.SIMPLE_BLANK_TABLE_TEMPLATE, { base64: true });
|
|
51
|
-
const tableData =
|
|
53
|
+
const tableData = utils_1.gridUtils.parseToTableData(grid);
|
|
52
54
|
if (tableData === undefined) {
|
|
53
55
|
throw new Error(constants_1.tableNotFoundErr);
|
|
54
56
|
}
|
|
55
|
-
yield utils_1.xmlPartsUtils.
|
|
57
|
+
yield utils_1.xmlPartsUtils.updateWorkbookDataAndConfigurations(zip, fileConfigs, tableData);
|
|
56
58
|
return yield zip.generateAsync({
|
|
57
59
|
type: constants_1.blobFileType,
|
|
58
60
|
mimeType: constants_1.application,
|
|
59
61
|
});
|
|
60
62
|
});
|
|
61
63
|
exports.generateTableWorkbookFromGrid = generateTableWorkbookFromGrid;
|
|
62
|
-
const
|
|
63
|
-
if (!grid) {
|
|
64
|
-
return undefined;
|
|
65
|
-
}
|
|
66
|
-
const tableData = (0, GridParser_1.parseToTableData)(grid);
|
|
67
|
-
return tableData;
|
|
68
|
-
});
|
|
69
|
-
const generateSingleQueryWorkbookFromZip = (zip, query, docProps, tableData) => __awaiter(void 0, void 0, void 0, function* () {
|
|
64
|
+
const generateSingleQueryWorkbookFromZip = (zip, query, fileConfigs, tableData) => __awaiter(void 0, void 0, void 0, function* () {
|
|
70
65
|
if (!query.queryName) {
|
|
71
66
|
query.queryName = constants_1.defaults.queryName;
|
|
72
67
|
}
|
|
73
68
|
yield utils_1.xmlPartsUtils.updateWorkbookPowerQueryDocument(zip, query.queryName, (0, generators_1.generateSingleQueryMashup)(query.queryName, query.queryMashup));
|
|
74
69
|
yield utils_1.xmlPartsUtils.updateWorkbookSingleQueryAttributes(zip, query.queryName, query.refreshOnOpen);
|
|
75
|
-
yield utils_1.xmlPartsUtils.
|
|
70
|
+
yield utils_1.xmlPartsUtils.updateWorkbookDataAndConfigurations(zip, fileConfigs, tableData, true /*updateQueryTable*/);
|
|
76
71
|
return yield zip.generateAsync({
|
|
77
72
|
type: constants_1.blobFileType,
|
|
78
73
|
mimeType: constants_1.application,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microsoft/connected-workbooks",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Microsoft backed, Excel advanced xlsx workbook generation JavaScript library",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"build": "tsc",
|
|
15
15
|
"build-webpack-prod": "webpack --mode=production --node-env=production",
|
|
16
16
|
"build-webpack-dev": "webpack --mode=development --node-env=development",
|
|
17
|
-
"test": "jest",
|
|
17
|
+
"test": "tsc --project tsconfig.test.json && jest",
|
|
18
18
|
"format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" --config .prettierrc"
|
|
19
19
|
},
|
|
20
20
|
"repository": {
|
|
@@ -38,7 +38,9 @@
|
|
|
38
38
|
"homepage": "https://github.com/microsoft/connected-workbooks#readme",
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"base64-js": "^1.5.1",
|
|
41
|
-
"
|
|
41
|
+
"buffer": "^6.0.3",
|
|
42
|
+
"jszip": "^3.5.0",
|
|
43
|
+
"uuid": "^9.0.0"
|
|
42
44
|
},
|
|
43
45
|
"devDependencies": {
|
|
44
46
|
"@babel/core": "^7.14.6",
|