@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,63 @@
1
+ "use strict";
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT license.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ const utils_1 = require("../src/utils");
6
+ const mocks_1 = require("./mocks");
7
+ describe("Table Utils tests", () => {
8
+ test("tests workbookXML contains initial data dimensions", () => {
9
+ const defaultString = '<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x15 xr xr6 xr10 xr2" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main" xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision" xmlns:xr6="http://schemas.microsoft.com/office/spreadsheetml/2016/revision6" xmlns:xr10="http://schemas.microsoft.com/office/spreadsheetml/2016/revision10" xmlns:xr2="http://schemas.microsoft.com/office/spreadsheetml/2015/revision2"><fileVersion appName="xl" lastEdited="7" lowestEdited="7" rupBuild="24729"/><workbookPr codeName="ThisWorkbook" defaultThemeVersion="166925"/><mc:AlternateContent><mc:Choice Requires="x15"><x15ac:absPath url="C:Usersv-ahmadsbeihDesktop" xmlns:x15ac="http://schemas.microsoft.com/office/spreadsheetml/2010/11/ac"/></mc:Choice></mc:AlternateContent><xr:revisionPtr revIDLastSave="0" documentId="13_ncr:1_{93EF201C-7856-4B60-94D4-65DDB8F3F16A}" xr6:coauthVersionLast="47" xr6:coauthVersionMax="47" xr10:uidLastSave="{00000000-0000-0000-0000-000000000000}"/><bookViews><workbookView xWindow="28680" yWindow="-120" windowWidth="29040" windowHeight="15990" xr2:uid="{DB915CB9-8DD9-492A-A471-C61E61200113}"/></bookViews><sheets><sheet name="Query1" sheetId="2" r:id="rId1"/><sheet name="Sheet1" sheetId="1" r:id="rId2"/></sheets><definedNames><definedName name="ExternalData_1" localSheetId="0" hidden="1">Sheet1!$A$1:$B$2</definedName></definedNames><calcPr calcId="191029"/><extLst><ext uri="{140A7094-0E35-4892-8432-C4D2E57EDEB5}"><x15:workbookPr chartTrackingRefBase="1"/></ext><ext uri="{B58B0392-4F1F-4190-BB64-5DF3571DCE5F}" xmlns:xcalcf="http://schemas.microsoft.com/office/spreadsheetml/2018/calcfeatures"><xcalcf:calcFeatures><xcalcf:feature name="microsoft.com:RD"/><xcalcf:feature name="microsoft.com:FV"/><xcalcf:feature name="microsoft.com:LET_WF"/><xcalcf:feature name="microsoft.com:LAMBDA_WF"/></xcalcf:calcFeatures></ext></extLst></workbook>';
10
+ const worksheetXml = utils_1.tableUtils.updateWorkbookInitialData(defaultString, {
11
+ columnNames: ["Column1", "Column2"],
12
+ rows: [["1", "2"]],
13
+ });
14
+ expect(worksheetXml).toContain(mocks_1.workbookXmlMock);
15
+ });
16
+ test("tests Pivot Tables contain initial data", () => {
17
+ const defaultString = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n<table xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="xr xr3" xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision" xmlns:xr3="http://schemas.microsoft.com/office/spreadsheetml/2016/revision3" id="1" xr:uid="{D8539CF6-04E5-464D-9950-5A36C5A1FCFE}" name="Query1" displayName="Query1" ref="A1:A2" tableType="queryTable" totalsRowShown="0"><autoFilter ref="A1:A2" xr:uid="{D8539CF6-04E5-464D-9950-5A36C5A1FCFE}"/><tableColumns count="1"><tableColumn id="1" xr3:uid="{D1084858-8AE5-4728-A9BE-FE78821CDFFF}" uniqueName="1" name="Query1" queryTableFieldId="1" dataDxfId="0"/></tableColumns><tableStyleInfo name="TableStyleMedium7" showFirstColumn="0" showLastColumn="0" showRowStripes="1" showColumnStripes="0"/></table>';
18
+ const tableXmlSheet = utils_1.tableUtils.updateTablesInitialData(defaultString, {
19
+ columnNames: ["Column1", "Column2"],
20
+ rows: [["1", "2"]],
21
+ }, true);
22
+ expect(tableXmlSheet).toContain('count="2"');
23
+ expect(tableXmlSheet).toContain('ref="A1:B2');
24
+ expect(tableXmlSheet).toContain('uniqueName="1"');
25
+ expect(tableXmlSheet).toContain('name="Column1"');
26
+ expect(tableXmlSheet).toContain('queryTableFieldId="1"');
27
+ expect(tableXmlSheet).toContain('uniqueName="2"');
28
+ expect(tableXmlSheet).toContain('name="Column2"');
29
+ expect(tableXmlSheet).toContain('queryTableFieldId="2"');
30
+ });
31
+ test("tests blank Table contain initial data", () => {
32
+ const defaultString = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n<table xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="xr xr3" xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision" xmlns:xr3="http://schemas.microsoft.com/office/spreadsheetml/2016/revision3" id="1" xr:uid="{D8539CF6-04E5-464D-9950-5A36C5A1FCFE}" name="Query1" displayName="Query1" ref="A1:A2" tableType="queryTable" totalsRowShown="0"><autoFilter ref="A1:A2" xr:uid="{D8539CF6-04E5-464D-9950-5A36C5A1FCFE}"/><tableColumns count="1"><tableColumn id="1" xr3:uid="{D1084858-8AE5-4728-A9BE-FE78821CDFFF}" uniqueName="1" name="Query1" queryTableFieldId="1" dataDxfId="0"/></tableColumns><tableStyleInfo name="TableStyleMedium7" showFirstColumn="0" showLastColumn="0" showRowStripes="1" showColumnStripes="0"/></table>';
33
+ const tableXmlSheet = utils_1.tableUtils.updateTablesInitialData(defaultString, {
34
+ columnNames: ["Column1", "Column2"],
35
+ rows: [["1", "2"]],
36
+ }, false);
37
+ expect(tableXmlSheet).toContain('count="2"');
38
+ expect(tableXmlSheet).toContain('ref="A1:B2');
39
+ expect(tableXmlSheet).toContain('name="Column2"');
40
+ expect(tableXmlSheet).toContain('name="Column1"');
41
+ // Not contains query table metadata.
42
+ expect(tableXmlSheet).not.toContain('uniqueName="1"');
43
+ expect(tableXmlSheet).not.toContain('queryTableFieldId="1"');
44
+ expect(tableXmlSheet).not.toContain('uniqueName="2"');
45
+ expect(tableXmlSheet).not.toContain('queryTableFieldId="2"');
46
+ });
47
+ test("test valid initial data in SheetsXML", () => {
48
+ const defaultString = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac xr xr2 xr3" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision" xmlns:xr2="http://schemas.microsoft.com/office/spreadsheetml/2015/revision2" xmlns:xr3="http://schemas.microsoft.com/office/spreadsheetml/2016/revision3" xr:uid="{EDF0138E-D216-4CD1-8EFA-1396A1BB4478}"><sheetPr codeName="Sheet1"/><dimension ref="A1:A2"/><sheetViews><sheetView tabSelected="1" workbookViewId="0"/></sheetViews><sheetFormatPr defaultRowHeight="14.4" x14ac:dyDescent="0.3"/><cols><col min="1" max="1" width="9.6640625" bestFit="1" customWidth="1"/></cols><sheetData><row r="1" spans="1:1" x14ac:dyDescent="0.3"><c r="A1" t="s"><v>0</v></c></row><row r="2" spans="1:1" x14ac:dyDescent="0.3"><c r="A2" t="s"><v>1</v></c></row></sheetData><pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/><tableParts count="1"><tablePart r:id="rId1"/></tableParts></worksheet>';
49
+ const sheetsXmlString = utils_1.tableUtils.updateSheetsInitialData(defaultString, {
50
+ columnNames: ["Column1", "Column2"],
51
+ rows: [["1", "2"]],
52
+ });
53
+ expect(sheetsXmlString).toContain(mocks_1.sheetsXmlMock);
54
+ });
55
+ test("tests Query Tables contain initial data", () => {
56
+ const defaultString = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n<queryTable xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="xr16" xmlns:xr16="http://schemas.microsoft.com/office/spreadsheetml/2017/revision16" name="ExternalData_1" connectionId="1" xr16:uid="{24C17B89-3CD3-4AA5-B84F-9FF5F35245D7}" autoFormatId="16" applyNumberFormats="0" applyBorderFormats="0" applyFontFormats="0" applyPatternFormats="0" applyAlignmentFormats="0" applyWidthHeightFormats="0"><queryTableRefresh nextId="2"><queryTableFields count="1"><queryTableField id="1" name="Query1" tableColumnId="1"/></queryTableFields></queryTableRefresh></queryTable>';
57
+ const queryTableXmlSheet = utils_1.tableUtils.updateQueryTablesInitialData(defaultString, {
58
+ columnNames: ["Column1", "Column2"],
59
+ rows: [["1", "2"]],
60
+ });
61
+ expect(queryTableXmlSheet).toContain(mocks_1.queryTableMock);
62
+ });
63
+ });
@@ -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 utils_1 = require("../src/utils");
18
+ const constants_1 = require("../src/utils/constants");
19
+ const mashupDocumentParser_1 = require("../src/utils/mashupDocumentParser");
20
+ const workbookTemplate_1 = require("../src/workbookTemplate");
21
+ const mocks_1 = require("./mocks");
22
+ const jszip_1 = __importDefault(require("jszip"));
23
+ const getZip = (template) => __awaiter(void 0, void 0, void 0, function* () {
24
+ return yield jszip_1.default.loadAsync(template, {
25
+ base64: true,
26
+ });
27
+ });
28
+ describe("Single query template tests", () => {
29
+ const singleQueryDefaultTemplate = workbookTemplate_1.SIMPLE_QUERY_WORKBOOK_TEMPLATE;
30
+ let defaultZipFile;
31
+ beforeAll(() => __awaiter(void 0, void 0, void 0, function* () {
32
+ expect(() => __awaiter(void 0, void 0, void 0, function* () { return yield getZip(singleQueryDefaultTemplate); })).not.toThrow();
33
+ defaultZipFile = yield getZip(singleQueryDefaultTemplate);
34
+ }));
35
+ test("Default template is a valid zip file", () => __awaiter(void 0, void 0, void 0, function* () {
36
+ expect(defaultZipFile).toBeTruthy();
37
+ }));
38
+ test("DataMashup XML exists, and valid PQ Base64 can be extracted", () => __awaiter(void 0, void 0, void 0, function* () {
39
+ expect(() => __awaiter(void 0, void 0, void 0, function* () { return yield utils_1.pqUtils.getDataMashupFile(defaultZipFile); })).not.toThrowError();
40
+ const { found, path, value } = yield utils_1.pqUtils.getDataMashupFile(defaultZipFile);
41
+ expect(found).toBeTruthy();
42
+ expect(value).toEqual(mocks_1.pqEmptySingleQueryBase64);
43
+ expect(path).toEqual(mocks_1.item1Path);
44
+ }));
45
+ test("ConnectedWorkbook XML exists as item1.xml", () => __awaiter(void 0, void 0, void 0, function* () {
46
+ const { found, path, xmlString } = yield utils_1.pqUtils.getCustomXmlFile(defaultZipFile, constants_1.URLS.CONNECTED_WORKBOOK, "utf-8");
47
+ expect(found).toBeTruthy();
48
+ expect(xmlString).toEqual(mocks_1.connectedWorkbookXmlMock);
49
+ expect(path).toEqual(mocks_1.item2Path);
50
+ }));
51
+ test("A single blank query named Query1 exists", () => __awaiter(void 0, void 0, void 0, function* () {
52
+ var _a;
53
+ const base64Str = yield utils_1.pqUtils.getBase64(defaultZipFile);
54
+ const { packageOPC } = (0, mashupDocumentParser_1.getPackageComponents)(base64Str);
55
+ const packageZip = yield jszip_1.default.loadAsync(packageOPC);
56
+ const section1m = yield ((_a = packageZip.file(constants_1.section1mPath)) === null || _a === void 0 ? void 0 : _a.async(constants_1.textResultType));
57
+ if (section1m == undefined) {
58
+ throw new Error("section1m is undefined");
59
+ }
60
+ const hasQuery1 = section1m.includes("Query1");
61
+ expect(hasQuery1).toBeTruthy();
62
+ expect(section1m).toEqual(mocks_1.section1mBlankQueryMock);
63
+ }));
64
+ });
@@ -0,0 +1,54 @@
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 workbookTemplate_1 = require("../src/workbookTemplate");
18
+ const utils_1 = require("../src/utils");
19
+ const constants_1 = require("../src/utils/constants");
20
+ const jszip_1 = __importDefault(require("jszip"));
21
+ const getZip = (template) => __awaiter(void 0, void 0, void 0, function* () {
22
+ return yield jszip_1.default.loadAsync(template, {
23
+ base64: true,
24
+ });
25
+ });
26
+ describe("Single blank table template tests", () => {
27
+ const simpleTableDefaultTemplate = workbookTemplate_1.SIMPLE_BLANK_TABLE_TEMPLATE;
28
+ let defaultZipFile;
29
+ beforeAll(() => __awaiter(void 0, void 0, void 0, function* () {
30
+ expect(() => __awaiter(void 0, void 0, void 0, function* () { return yield getZip(simpleTableDefaultTemplate); })).not.toThrow();
31
+ defaultZipFile = yield getZip(simpleTableDefaultTemplate);
32
+ }));
33
+ test("Default template is a valid zip file", () => {
34
+ expect(defaultZipFile).toBeTruthy();
35
+ });
36
+ test("DataMashup XML doesn't exists", () => __awaiter(void 0, void 0, void 0, function* () {
37
+ try {
38
+ yield utils_1.pqUtils.getDataMashupFile(defaultZipFile);
39
+ }
40
+ catch (error) {
41
+ expect(error).toBeTruthy();
42
+ }
43
+ }));
44
+ test("A single blank table exists", () => __awaiter(void 0, void 0, void 0, function* () {
45
+ var _a;
46
+ const tableXml = yield ((_a = defaultZipFile.file(constants_1.tableXmlPath)) === null || _a === void 0 ? void 0 : _a.async(constants_1.textResultType));
47
+ expect(tableXml).toContain('name="Table1" displayName="Table1" ref="A1:A2"');
48
+ }));
49
+ test("Does not contains query table", () => __awaiter(void 0, void 0, void 0, function* () {
50
+ var _b;
51
+ const queryTableXml = yield ((_b = defaultZipFile.file(constants_1.queryTableXmlPath)) === null || _b === void 0 ? void 0 : _b.async(constants_1.textResultType));
52
+ expect(queryTableXml).toBeFalsy();
53
+ }));
54
+ });
@@ -0,0 +1,51 @@
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 mocks_1 = require("./mocks");
15
+ const utils_1 = require("../src/utils");
16
+ describe("Workbook Manager tests", () => {
17
+ const mockConnectionString = `<connections xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:xr16="http://schemas.microsoft.com/office/spreadsheetml/2017/revision16" mc:Ignorable="xr16">
18
+ <connection id="1" xr16:uid="{86BA784C-6640-4989-A85E-EB4966B9E741}" keepAlive="1" name="Query - Query1" description="Connection to the 'Query1' query in the workbook." type="5" refreshedVersion="7" background="1" saveData="1">
19
+ <dbPr connection="Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=Query1;" command="SELECT * FROM [Query1]"/></connection></connections>`;
20
+ test("Connection XML attributes contain new query name", () => __awaiter(void 0, void 0, void 0, function* () {
21
+ const { connectionXmlFileString } = yield utils_1.xmlInnerPartsUtils.updateConnections(mockConnectionString, "newQueryName", true);
22
+ expect(connectionXmlFileString.replace(/ /g, "")).toContain('command="SELECT * FROM [newQueryName]'.replace(/ /g, ""));
23
+ expect(connectionXmlFileString.replace(/ /g, "")).toContain('name="Query - newQueryName"'.replace(/ /g, ""));
24
+ expect(connectionXmlFileString.replace(/ /g, "")).toContain(`description="Connection to the 'newQueryName' query in the workbook."`.replace(/ /g, ""));
25
+ }));
26
+ test("Connection XML attributes contain refreshOnLoad value", () => __awaiter(void 0, void 0, void 0, function* () {
27
+ const { connectionXmlFileString } = yield utils_1.xmlInnerPartsUtils.updateConnections(mockConnectionString, "newQueryName", true);
28
+ expect(connectionXmlFileString.replace(/ /g, "")).toContain('refreshOnLoad="1"');
29
+ }));
30
+ test("SharedStrings XML contains new query name", () => __awaiter(void 0, void 0, void 0, function* () {
31
+ const { newSharedStrings } = yield utils_1.xmlInnerPartsUtils.updateSharedStrings('<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="1" uniqueCount="1"><si><t>Query1</t></si><si><t/></si></sst>', "newQueryName");
32
+ expect(newSharedStrings.replace(/ /g, "")).toContain(mocks_1.sharedStringsXmlMock.replace(/ /g, ""));
33
+ }));
34
+ test("Tests SharedStrings update when XML contains query name", () => __awaiter(void 0, void 0, void 0, function* () {
35
+ const { newSharedStrings } = yield utils_1.xmlInnerPartsUtils.updateSharedStrings('<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="1" uniqueCount="1"><si><t>newQueryName</t></si><si><t/></si></sst>', "newQueryName");
36
+ expect(newSharedStrings.replace(/ /g, "")).toContain(mocks_1.existingSharedStringsXmlMock.replace(/ /g, ""));
37
+ }));
38
+ test("SharedStrings XML returns new index", () => __awaiter(void 0, void 0, void 0, function* () {
39
+ const { sharedStringIndex } = yield utils_1.xmlInnerPartsUtils.updateSharedStrings('<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="1" uniqueCount="1"><si><t>Query1</t></si><si><t/></si></sst>', "newQueryName");
40
+ expect(sharedStringIndex).toEqual(2);
41
+ }));
42
+ test("SharedStrings XML returns existing index", () => __awaiter(void 0, void 0, void 0, function* () {
43
+ const { sharedStringIndex } = yield utils_1.xmlInnerPartsUtils.updateSharedStrings('<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="1" uniqueCount="1"><si><t>newQueryName</t></si><si><t/></si></sst>', "newQueryName");
44
+ expect(sharedStringIndex).toEqual(1);
45
+ }));
46
+ test("Table XML contains refrshonload value", () => __awaiter(void 0, void 0, void 0, function* () {
47
+ const { sharedStringIndex, newSharedStrings } = yield utils_1.xmlInnerPartsUtils.updateSharedStrings('<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="1" uniqueCount="1"><si><t>Query1</t></si><si><t/></si></sst>', "newQueryName");
48
+ expect(sharedStringIndex).toEqual(2);
49
+ expect(newSharedStrings.replace(/ /g, "")).toContain(mocks_1.sharedStringsXmlMock.replace(/ /g, ""));
50
+ }));
51
+ });
package/dist/types.d.ts CHANGED
@@ -17,23 +17,22 @@ export interface Metadata {
17
17
  queryName: string;
18
18
  }
19
19
  export interface TableData {
20
- columnMetadata: ColumnMetadata[];
20
+ columnNames: string[];
21
21
  rows: string[][];
22
- columnwidth?: number;
23
- }
24
- export interface ColumnMetadata {
25
- name: string;
26
- type: DataTypes;
27
22
  }
28
23
  export interface Grid {
29
- header: ColumnMetadata[];
30
- gridData: (string | number | boolean)[][];
24
+ data: (string | number | boolean)[][];
25
+ config?: GridConfig;
26
+ }
27
+ export interface GridConfig {
28
+ promoteHeaders?: boolean;
29
+ adjustColumnNames?: boolean;
31
30
  }
32
- export interface TableDataParser {
33
- parseToTableData: (grid: any) => TableData | undefined;
31
+ export interface FileConfigs {
32
+ templateFile?: File;
33
+ docProps?: DocProps;
34
34
  }
35
35
  export declare enum DataTypes {
36
- autodetect = -1,
37
36
  null = 0,
38
37
  string = 1,
39
38
  number = 2,
package/dist/types.js CHANGED
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.DocPropsAutoUpdatedElements = exports.DocPropsModifiableElements = exports.DataTypes = void 0;
6
6
  var DataTypes;
7
7
  (function (DataTypes) {
8
- DataTypes[DataTypes["autodetect"] = -1] = "autodetect";
9
8
  DataTypes[DataTypes["null"] = 0] = "null";
10
9
  DataTypes[DataTypes["string"] = 1] = "string";
11
10
  DataTypes[DataTypes["number"] = 2] = "number";
@@ -2,7 +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.URLS = exports.defaults = exports.elementAttributesValues = exports.dataTypeKind = exports.elementAttributes = exports.element = exports.falseStr = exports.trueStr = 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.stylesNotFoundErr = exports.EmptyQueryNameErr = exports.QueryNameMaxLengthErr = exports.invalidDataTypeErr = exports.headerNotFoundErr = exports.invalidValueInColumnErr = exports.gridNotFoundErr = 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.docPropsCoreXmlPath = exports.section1mPath = exports.pivotCachesPath = exports.queryTablesPath = exports.workbookXmlPath = exports.queryTableXmlPath = exports.tableXmlPath = exports.sheetsXmlPath = exports.sharedStringsXmlPath = exports.connectionsXmlPath = void 0;
5
+ exports.element = exports.BOM = exports.falseStr = exports.trueStr = 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.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.docPropsCoreXmlPath = exports.section1mPath = exports.pivotCachesPath = exports.queryTablesPath = exports.workbookXmlPath = exports.queryTableXmlPath = exports.tableXmlPath = exports.sheetsXmlPath = exports.sharedStringsXmlPath = exports.connectionsXmlPath = void 0;
6
+ exports.URLS = exports.defaults = exports.elementAttributesValues = exports.dataTypeKind = exports.elementAttributes = void 0;
6
7
  exports.connectionsXmlPath = "xl/connections.xml";
7
8
  exports.sharedStringsXmlPath = "xl/sharedStrings.xml";
8
9
  exports.sheetsXmlPath = "xl/worksheets/sheet1.xml";
@@ -26,13 +27,17 @@ exports.formulaSectionNotFoundErr = "Formula section wasn't found in template";
26
27
  exports.templateWithInitialDataErr = "Cannot receive template file with initial data";
27
28
  exports.queryTableNotFoundErr = "Query table wasn't found in template";
28
29
  exports.tableNotFoundErr = "Table wasn't found in template";
29
- exports.gridNotFoundErr = "Invalid JSON file, grid data is missing";
30
30
  exports.invalidValueInColumnErr = "Invalid cell value in column";
31
31
  exports.headerNotFoundErr = "Invalid JSON file, header is missing";
32
32
  exports.invalidDataTypeErr = "Invalid JSON file, invalid data type";
33
33
  exports.QueryNameMaxLengthErr = "Query names are limited to 80 characters";
34
+ exports.QueryNameInvalidCharsErr = 'Query names cannot contain periods or quotation marks. (. ")';
34
35
  exports.EmptyQueryNameErr = "Query name cannot be empty";
35
36
  exports.stylesNotFoundErr = "Styles were not found in template";
37
+ exports.InvalidColumnNameErr = "Invalid column name";
38
+ exports.promotedHeadersCannotBeUsedWithoutAdjustingColumnNamesErr = "Headers cannot be promoted without adjusting column names";
39
+ exports.unexpectedErr = "Unexpected error";
40
+ exports.arrayIsntMxNErr = "Array isn't MxN";
36
41
  exports.blobFileType = "blob";
37
42
  exports.uint8ArrayType = "uint8array";
38
43
  exports.application = "application/xlsx";
@@ -47,6 +52,7 @@ exports.divider = "/";
47
52
  exports.maxQueryLength = 80;
48
53
  exports.trueStr = "true";
49
54
  exports.falseStr = "false";
55
+ exports.BOM = "\ufeff";
50
56
  exports.element = {
51
57
  sharedStringTable: "sst",
52
58
  text: "t",
@@ -73,7 +79,8 @@ exports.element = {
73
79
  sheetData: "sheetData",
74
80
  row: "row",
75
81
  dimension: "dimension",
76
- kindCell: "c"
82
+ selection: "selection",
83
+ kindCell: "c",
77
84
  };
78
85
  exports.elementAttributes = {
79
86
  connection: "connection",
@@ -98,6 +105,7 @@ exports.elementAttributes = {
98
105
  uniqueName: "uniqueName",
99
106
  queryTableFieldId: "queryTableFieldId",
100
107
  reference: "ref",
108
+ sqref: "sqref",
101
109
  tableColumnId: "tableColumnId",
102
110
  nextId: "nextId",
103
111
  row: "r",
@@ -113,12 +121,14 @@ exports.dataTypeKind = {
113
121
  exports.elementAttributesValues = {
114
122
  connectionName: (queryName) => `Query - ${queryName}`,
115
123
  connectionDescription: (queryName) => `Connection to the '${queryName}' query in the workbook.`,
116
- connection: (queryName) => `Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=${queryName};`,
124
+ connection: (queryName) => `Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location="${queryName}";`,
117
125
  connectionCommand: (queryName) => `SELECT * FROM [${queryName}]`,
118
- tableResultType: () => "sTable"
126
+ tableResultType: () => "sTable",
119
127
  };
120
128
  exports.defaults = {
121
129
  queryName: "Query1",
130
+ sheetName: "Sheet1",
131
+ columnName: "Column",
122
132
  };
123
133
  exports.URLS = {
124
134
  PQ: [
@@ -55,16 +55,16 @@ const getCellReferenceRelative = (col, row) => {
55
55
  const getTableReference = (numberOfCols, numberOfRows) => {
56
56
  return `A1:${getCellReferenceRelative(numberOfCols, numberOfRows)}`;
57
57
  };
58
- const createCellElement = (doc, colIndex, rowIndex, dataType, data) => {
58
+ const createCellElement = (doc, colIndex, rowIndex, data) => {
59
59
  const cell = doc.createElementNS(doc.documentElement.namespaceURI, constants_1.element.kindCell);
60
60
  cell.setAttribute(constants_1.elementAttributes.row, getCellReferenceRelative(colIndex, rowIndex + 1));
61
61
  const cellData = doc.createElementNS(doc.documentElement.namespaceURI, constants_1.element.cellValue);
62
- updateCellData(dataType, data, cell, cellData);
62
+ updateCellData(data, cell, cellData, rowIndex === 0);
63
63
  cell.appendChild(cellData);
64
64
  return cell;
65
65
  };
66
- const updateCellData = (dataType, data, cell, cellData) => {
67
- switch (resolveType(dataType, data)) {
66
+ const updateCellData = (data, cell, cellData, rowHeader) => {
67
+ switch (resolveType(data, rowHeader)) {
68
68
  case types_1.DataTypes.string:
69
69
  cell.setAttribute(constants_1.element.text, constants_1.dataTypeKind.string);
70
70
  break;
@@ -77,14 +77,15 @@ const updateCellData = (dataType, data, cell, cellData) => {
77
77
  }
78
78
  cellData.textContent = data;
79
79
  };
80
- const resolveType = (originalDataType, originalData) => {
81
- if (originalDataType !== types_1.DataTypes.autodetect) {
82
- return originalDataType;
83
- }
80
+ const resolveType = (originalData, rowHeader) => {
84
81
  const data = originalData;
82
+ if (rowHeader) {
83
+ // Headers should be string by default.
84
+ return types_1.DataTypes.string;
85
+ }
85
86
  let dataType = isNaN(Number(data)) ? types_1.DataTypes.string : types_1.DataTypes.number;
86
87
  if (dataType == types_1.DataTypes.string) {
87
- if (data.toLowerCase().trim() == constants_1.trueStr || data.toLowerCase().trim() == constants_1.falseStr) {
88
+ if (data.trim() == constants_1.trueStr || data.trim() == constants_1.falseStr) {
88
89
  dataType = types_1.DataTypes.boolean;
89
90
  }
90
91
  }
@@ -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 };
@@ -1,17 +1,11 @@
1
1
  "use strict";
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT license.
2
4
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.extractTableValues = void 0;
4
5
  const extractTableValues = (table) => {
5
- const headers = [];
6
6
  const rows = [];
7
- // Extract headers
8
- const headerRow = table.rows[0];
9
- for (let i = 0; i < headerRow.cells.length; i++) {
10
- const cell = headerRow.cells[i];
11
- headers.push(cell.textContent || "");
12
- }
13
7
  // Extract values from each row
14
- for (let i = 1; i < table.rows.length; i++) {
8
+ for (let i = 0; i < table.rows.length; i++) {
15
9
  const row = table.rows[i];
16
10
  const rowData = [];
17
11
  for (let j = 0; j < row.cells.length; j++) {
@@ -20,6 +14,6 @@ const extractTableValues = (table) => {
20
14
  }
21
15
  rows.push(rowData);
22
16
  }
23
- return [headers, rows];
17
+ return rows;
24
18
  };
25
- exports.extractTableValues = extractTableValues;
19
+ exports.default = { extractTableValues };
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  return (mod && mod.__esModule) ? mod : { "default": mod };
6
6
  };
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.tableUtils = exports.xmlInnerPartsUtils = exports.xmlPartsUtils = exports.documentUtils = exports.arrayUtils = exports.pqUtils = void 0;
8
+ exports.gridUtils = exports.htmlUtils = exports.tableUtils = exports.xmlInnerPartsUtils = exports.xmlPartsUtils = exports.documentUtils = exports.arrayUtils = exports.pqUtils = void 0;
9
9
  var pqUtils_1 = require("./pqUtils");
10
10
  Object.defineProperty(exports, "pqUtils", { enumerable: true, get: function () { return __importDefault(pqUtils_1).default; } });
11
11
  var arrayUtils_1 = require("./arrayUtils");
@@ -18,3 +18,7 @@ var xmlInnerPartsUtils_1 = require("./xmlInnerPartsUtils");
18
18
  Object.defineProperty(exports, "xmlInnerPartsUtils", { enumerable: true, get: function () { return __importDefault(xmlInnerPartsUtils_1).default; } });
19
19
  var tableUtils_1 = require("./tableUtils");
20
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; } });