@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
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation.
|
|
3
|
+
// Licensed under the MIT license.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
const constants_1 = require("../utils/constants");
|
|
6
|
+
const parseToTableData = (grid) => {
|
|
7
|
+
var _a, _b, _c, _d;
|
|
8
|
+
if (grid === null || grid === undefined) {
|
|
9
|
+
grid = { data: [] };
|
|
10
|
+
}
|
|
11
|
+
if (grid.data === null || grid.data === undefined) {
|
|
12
|
+
grid.data = [];
|
|
13
|
+
}
|
|
14
|
+
const mergedGrid = {
|
|
15
|
+
config: {
|
|
16
|
+
promoteHeaders: (_b = (_a = grid.config) === null || _a === void 0 ? void 0 : _a.promoteHeaders) !== null && _b !== void 0 ? _b : false,
|
|
17
|
+
adjustColumnNames: (_d = (_c = grid.config) === null || _c === void 0 ? void 0 : _c.adjustColumnNames) !== null && _d !== void 0 ? _d : true,
|
|
18
|
+
},
|
|
19
|
+
data: grid.data.map((row) => row.map((value) => { var _a; return (_a = value === null || value === void 0 ? void 0 : value.toString()) !== null && _a !== void 0 ? _a : ""; })),
|
|
20
|
+
};
|
|
21
|
+
correctGrid(mergedGrid);
|
|
22
|
+
validateGrid(mergedGrid);
|
|
23
|
+
let columnNames = [];
|
|
24
|
+
if (mergedGrid.config.promoteHeaders && mergedGrid.config.adjustColumnNames) {
|
|
25
|
+
columnNames = getAdjustedColumnNames(mergedGrid.data.shift());
|
|
26
|
+
}
|
|
27
|
+
else if (mergedGrid.config.promoteHeaders && !mergedGrid.config.adjustColumnNames) {
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
29
|
+
columnNames = mergedGrid.data.shift();
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
columnNames = Array.from({ length: mergedGrid.data[0].length }, (_, index) => `${constants_1.defaults.columnName} ${index + 1}`);
|
|
33
|
+
}
|
|
34
|
+
return { columnNames: columnNames, rows: mergedGrid.data };
|
|
35
|
+
};
|
|
36
|
+
const correctGrid = (grid) => {
|
|
37
|
+
if (grid.data.length === 0) {
|
|
38
|
+
// empty grid fix
|
|
39
|
+
grid.config.promoteHeaders = false;
|
|
40
|
+
grid.data.push([""]);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const getEmptyArray = (n) => Array.from({ length: n }, () => "");
|
|
44
|
+
if (grid.data[0].length === 0) {
|
|
45
|
+
grid.data[0] = [""];
|
|
46
|
+
}
|
|
47
|
+
// replace empty rows
|
|
48
|
+
grid.data.forEach((row, index) => {
|
|
49
|
+
if (row.length === 0) {
|
|
50
|
+
grid.data[index] = getEmptyArray(grid.data[0].length);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
if (grid.config.promoteHeaders && grid.data.length === 1) {
|
|
54
|
+
// table in Excel should have at least 2 rows
|
|
55
|
+
grid.data.push(getEmptyArray(grid.data[0].length));
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
/*
|
|
59
|
+
* Validates the grid, throws an error if the grid is invalid.
|
|
60
|
+
* A valid grid has:
|
|
61
|
+
* - MxN structure.
|
|
62
|
+
* - If promoteHeaders is true - has at least 1 row, and in case adjustColumnNames is false, first row is unique and non empty.
|
|
63
|
+
*/
|
|
64
|
+
const validateGrid = (grid) => {
|
|
65
|
+
validateDataArrayDimensions(grid.data);
|
|
66
|
+
if (grid.config.promoteHeaders && grid.config.adjustColumnNames === false && !validateUniqueAndValidDataArray(grid.data[0])) {
|
|
67
|
+
throw new Error(constants_1.promotedHeadersCannotBeUsedWithoutAdjustingColumnNamesErr);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const validateDataArrayDimensions = (arr) => {
|
|
71
|
+
if (arr.length === 0 || arr[0].length === 0) {
|
|
72
|
+
throw new Error(constants_1.unexpectedErr);
|
|
73
|
+
}
|
|
74
|
+
if (!arr.every((innerArr) => innerArr.length === arr[0].length)) {
|
|
75
|
+
throw new Error(constants_1.arrayIsntMxNErr);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const validateUniqueAndValidDataArray = (arr) => {
|
|
79
|
+
if (arr.some((element) => element === "")) {
|
|
80
|
+
return false; // Array contains empty elements
|
|
81
|
+
}
|
|
82
|
+
const uniqueSet = new Set(arr);
|
|
83
|
+
return uniqueSet.size === arr.length;
|
|
84
|
+
};
|
|
85
|
+
const getAdjustedColumnNames = (columnNames) => {
|
|
86
|
+
if (columnNames === undefined) {
|
|
87
|
+
throw new Error(constants_1.unexpectedErr);
|
|
88
|
+
}
|
|
89
|
+
let i = 1;
|
|
90
|
+
// replace empty column names with default names, can still conflict if columns exist, but we handle that later
|
|
91
|
+
columnNames = columnNames.map((columnName) => columnName || `${constants_1.defaults.columnName} ${i++}`);
|
|
92
|
+
const uniqueNames = new Set();
|
|
93
|
+
return columnNames.map((name) => {
|
|
94
|
+
let uniqueName = name;
|
|
95
|
+
i = 1;
|
|
96
|
+
while (uniqueNames.has(uniqueName)) {
|
|
97
|
+
uniqueName = `${name} (${i++})`;
|
|
98
|
+
}
|
|
99
|
+
uniqueNames.add(uniqueName);
|
|
100
|
+
return uniqueName;
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
exports.default = { parseToTableData };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation.
|
|
3
|
+
// Licensed under the MIT license.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
const extractTableValues = (table) => {
|
|
6
|
+
const rows = [];
|
|
7
|
+
// Extract values from each row
|
|
8
|
+
for (let i = 0; i < table.rows.length; i++) {
|
|
9
|
+
const row = table.rows[i];
|
|
10
|
+
const rowData = [];
|
|
11
|
+
for (let j = 0; j < row.cells.length; j++) {
|
|
12
|
+
const cell = row.cells[j];
|
|
13
|
+
rowData.push(cell.textContent || "");
|
|
14
|
+
}
|
|
15
|
+
rows.push(rowData);
|
|
16
|
+
}
|
|
17
|
+
return rows;
|
|
18
|
+
};
|
|
19
|
+
exports.default = { extractTableValues };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation.
|
|
3
|
+
// Licensed under the MIT license.
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.gridUtils = exports.htmlUtils = exports.tableUtils = exports.xmlInnerPartsUtils = exports.xmlPartsUtils = exports.documentUtils = exports.arrayUtils = exports.pqUtils = void 0;
|
|
9
|
+
var pqUtils_1 = require("./pqUtils");
|
|
10
|
+
Object.defineProperty(exports, "pqUtils", { enumerable: true, get: function () { return __importDefault(pqUtils_1).default; } });
|
|
11
|
+
var arrayUtils_1 = require("./arrayUtils");
|
|
12
|
+
Object.defineProperty(exports, "arrayUtils", { enumerable: true, get: function () { return __importDefault(arrayUtils_1).default; } });
|
|
13
|
+
var documentUtils_1 = require("./documentUtils");
|
|
14
|
+
Object.defineProperty(exports, "documentUtils", { enumerable: true, get: function () { return __importDefault(documentUtils_1).default; } });
|
|
15
|
+
var xmlPartsUtils_1 = require("./xmlPartsUtils");
|
|
16
|
+
Object.defineProperty(exports, "xmlPartsUtils", { enumerable: true, get: function () { return __importDefault(xmlPartsUtils_1).default; } });
|
|
17
|
+
var xmlInnerPartsUtils_1 = require("./xmlInnerPartsUtils");
|
|
18
|
+
Object.defineProperty(exports, "xmlInnerPartsUtils", { enumerable: true, get: function () { return __importDefault(xmlInnerPartsUtils_1).default; } });
|
|
19
|
+
var tableUtils_1 = require("./tableUtils");
|
|
20
|
+
Object.defineProperty(exports, "tableUtils", { enumerable: true, get: function () { return __importDefault(tableUtils_1).default; } });
|
|
21
|
+
var htmlUtils_1 = require("./htmlUtils");
|
|
22
|
+
Object.defineProperty(exports, "htmlUtils", { enumerable: true, get: function () { return __importDefault(htmlUtils_1).default; } });
|
|
23
|
+
var gridUtils_1 = require("./gridUtils");
|
|
24
|
+
Object.defineProperty(exports, "gridUtils", { enumerable: true, get: function () { return __importDefault(gridUtils_1).default; } });
|
|
@@ -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
|
+
const reference = documentUtils_1.default.getTableReference(tableData.rows[0].length - 1, tableData.rows.length + 1);
|
|
133
|
+
sheetsDoc.getElementsByTagName(constants_1.element.dimension)[0].setAttribute(constants_1.elementAttributes.reference, reference);
|
|
134
|
+
sheetsDoc.getElementsByTagName(constants_1.element.selection)[0].setAttribute(constants_1.elementAttributes.sqref, reference);
|
|
135
|
+
return serializer.serializeToString(sheetsDoc);
|
|
136
|
+
};
|
|
137
|
+
exports.default = {
|
|
138
|
+
updateTableInitialDataIfNeeded,
|
|
139
|
+
updateSheetsInitialData,
|
|
140
|
+
updateWorkbookInitialData,
|
|
141
|
+
updateTablesInitialData,
|
|
142
|
+
updateQueryTablesInitialData,
|
|
143
|
+
};
|