diff --git a/package-lock.json b/package-lock.json index c92551c..db9025c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,20 @@ { "name": "@microsoft/connected-workbooks", - "version": "2.1.26", + "version": "3.0.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@microsoft/connected-workbooks", - "version": "2.1.26", + "version": "3.0.3", "license": "MIT", "dependencies": { "base64-js": "^1.5.1", "buffer": "^6.0.3", "jszip": "^3.5.0", - "uuid": "^9.0.0" + "uuid": "^9.0.0", + "xmldom": "^0.6.0", + "xmldom-qsa": "^1.1.3" }, "devDependencies": { "@babel/core": "^7.14.6", @@ -23,6 +25,7 @@ "@types/jszip": "^3.4.1", "@types/uuid": "^9.0.2", "@types/webpack-bundle-analyzer": "^4.6.0", + "@types/xmldom": "^0.1.32", "@typescript-eslint/eslint-plugin": "^4.28.2", "@typescript-eslint/parser": "^4.28.2", "@webpack-cli/generators": "^3.0.7", @@ -5291,6 +5294,12 @@ "webpack": "^5" } }, + "node_modules/@types/xmldom": { + "version": "0.1.32", + "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.32.tgz", + "integrity": "sha512-zPO1iqnODar0cIXhuCc0QyGP+t2IG9dr//VkxDtYKZJSikgN7bdLyMdnUNWRtCKeHkgc9KkbgsdccVbrCHCn2g==", + "dev": true + }, "node_modules/@types/yargs": { "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", @@ -9705,6 +9714,12 @@ "node": ">=0.4.0" } }, + "node_modules/jsdom/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -11530,12 +11545,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -14798,6 +14807,22 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "node_modules/xmldom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz", + "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/xmldom-qsa": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/xmldom-qsa/-/xmldom-qsa-1.1.3.tgz", + "integrity": "sha512-IJBOczBpAYrIBJFFsmCBwfBhwe4zdMR3Xz0ZBX0OFtgO49rLy/BWbhkegOwsthdBWb1gUtFK6ZZnGdT8ZqPRBA==", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -19750,6 +19775,12 @@ "webpack": "^5" } }, + "@types/xmldom": { + "version": "0.1.32", + "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.32.tgz", + "integrity": "sha512-zPO1iqnODar0cIXhuCc0QyGP+t2IG9dr//VkxDtYKZJSikgN7bdLyMdnUNWRtCKeHkgc9KkbgsdccVbrCHCn2g==", + "dev": true + }, "@types/yargs": { "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", @@ -23087,6 +23118,12 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", "dev": true + }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true } } }, @@ -24503,12 +24540,6 @@ "lines-and-columns": "^1.1.6" } }, - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -26937,6 +26968,16 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "xmldom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz", + "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==" + }, + "xmldom-qsa": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/xmldom-qsa/-/xmldom-qsa-1.1.3.tgz", + "integrity": "sha512-IJBOczBpAYrIBJFFsmCBwfBhwe4zdMR3Xz0ZBX0OFtgO49rLy/BWbhkegOwsthdBWb1gUtFK6ZZnGdT8ZqPRBA==" + }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 00bf185..b3a9d17 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/connected-workbooks", - "version": "3.0.0", + "version": "3.0.3", "description": "Microsoft backed, Excel advanced xlsx workbook generation JavaScript library", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -40,7 +40,9 @@ "base64-js": "^1.5.1", "buffer": "^6.0.3", "jszip": "^3.5.0", - "uuid": "^9.0.0" + "uuid": "^9.0.0", + "xmldom": "^0.6.0", + "xmldom-qsa": "^1.1.3" }, "devDependencies": { "@babel/core": "^7.14.6", @@ -51,6 +53,7 @@ "@types/jszip": "^3.4.1", "@types/uuid": "^9.0.2", "@types/webpack-bundle-analyzer": "^4.6.0", + "@types/xmldom": "^0.1.32", "@typescript-eslint/eslint-plugin": "^4.28.2", "@typescript-eslint/parser": "^4.28.2", "@webpack-cli/generators": "^3.0.7", diff --git a/src/utils/documentUtils.ts b/src/utils/documentUtils.ts index 030ca18..57cdd0e 100644 --- a/src/utils/documentUtils.ts +++ b/src/utils/documentUtils.ts @@ -2,6 +2,7 @@ // Licensed under the MIT license. import JSZip from "jszip"; +import { DOMParser } from "xmldom-qsa"; import { dataTypeKind, docPropsCoreXmlPath, diff --git a/src/utils/mashupDocumentParser.ts b/src/utils/mashupDocumentParser.ts index b7c58ca..88d7f56 100644 --- a/src/utils/mashupDocumentParser.ts +++ b/src/utils/mashupDocumentParser.ts @@ -3,6 +3,7 @@ import * as base64 from "base64-js"; import JSZip from "jszip"; +import { DOMParser, XMLSerializer } from "xmldom-qsa"; import { section1mPath, defaults, @@ -111,7 +112,7 @@ export const editSingleQueryMetadata = (metadataArray: Uint8Array, metadata: Met if (itemPaths && itemPaths.length) { for (let i = 0; i < itemPaths.length; i++) { const itemPath: Element = itemPaths[i]; - const content: string = itemPath.innerHTML; + const content: string = itemPath.textContent as string; if (content.includes(section1PathPrefix)) { const strArr: string[] = content.split(divider); strArr[1] = encodeURIComponent(metadata.queryName); @@ -125,8 +126,7 @@ export const editSingleQueryMetadata = (metadataArray: Uint8Array, metadata: Met if (entries && entries.length) { for (let i = 0; i < entries.length; i++) { const entry: Element = entries[i]; - const entryAttributes: NamedNodeMap = entry.attributes; - const entryAttributesArr: Attr[] = [...entryAttributes]; + const entryAttributesArr: Attr[] = Array.from(entry.attributes); const entryProp: Attr | undefined = entryAttributesArr.find((prop) => { return prop?.name === elementAttributes.type; }); diff --git a/src/utils/pqUtils.ts b/src/utils/pqUtils.ts index 4812320..dbc3a65 100644 --- a/src/utils/pqUtils.ts +++ b/src/utils/pqUtils.ts @@ -5,15 +5,16 @@ import JSZip from "jszip"; import { EmptyQueryNameErr, QueryNameMaxLengthErr, maxQueryLength, URLS, BOM, QueryNameInvalidCharsErr } from "./constants"; import { generateMashupXMLTemplate, generateCustomXmlFilePath } from "../generators"; import { Buffer } from "buffer"; +import { DOMParser } from "xmldom-qsa"; type CustomXmlFile = { found: boolean; path: string; xmlString: string | undefined; - value: string | undefined; + value: string | null; }; -const getBase64 = async (zip: JSZip): Promise => { +const getBase64 = async (zip: JSZip): Promise => { const mashup = await getDataMashupFile(zip); return mashup.value; }; @@ -54,7 +55,7 @@ const getCustomXmlFile = async (zip: JSZip, url: string, encoding: BufferEncodin let found = false; let path: string; let xmlString: string | undefined; - let value: string | undefined; + let value: string | null = null; for (let i = 1; i <= itemsArray.length; i++) { path = generateCustomXmlFilePath(i); @@ -72,7 +73,7 @@ const getCustomXmlFile = async (zip: JSZip, url: string, encoding: BufferEncodin found = doc?.documentElement?.namespaceURI === url; if (found) { - value = doc.documentElement.innerHTML; + value = doc.documentElement.textContent; break; } } diff --git a/src/utils/tableUtils.ts b/src/utils/tableUtils.ts index 4d1fc69..fa2e571 100644 --- a/src/utils/tableUtils.ts +++ b/src/utils/tableUtils.ts @@ -3,6 +3,7 @@ import JSZip from "jszip"; import { TableData } from "../types"; +import { DOMParser, XMLSerializer } from "xmldom-qsa"; import { defaults, element, diff --git a/src/utils/xmlInnerPartsUtils.ts b/src/utils/xmlInnerPartsUtils.ts index 4621221..8e1ebe1 100644 --- a/src/utils/xmlInnerPartsUtils.ts +++ b/src/utils/xmlInnerPartsUtils.ts @@ -2,6 +2,7 @@ // Licensed under the MIT license. import JSZip from "jszip"; +import { DOMParser, XMLSerializer } from "xmldom-qsa"; import { DocProps, DocPropsAutoUpdatedElements, DocPropsModifiableElements } from "../types"; import { docPropsCoreXmlPath, @@ -100,11 +101,11 @@ const updateConnections = ( dbPr.setAttribute(elementAttributes.refreshOnLoad, refreshOnLoadValue); // Update query details to match queryName - dbPr.parentElement?.setAttribute(elementAttributes.name, elementAttributesValues.connectionName(queryName)); - dbPr.parentElement?.setAttribute(elementAttributes.description, elementAttributesValues.connectionDescription(queryName)); + (dbPr.parentNode as Element)?.setAttribute(elementAttributes.name, elementAttributesValues.connectionName(queryName)); + (dbPr.parentNode as Element)?.setAttribute(elementAttributes.description, elementAttributesValues.connectionDescription(queryName)); dbPr.setAttribute(elementAttributes.connection, elementAttributesValues.connection(queryName)); dbPr.setAttribute(elementAttributes.command, elementAttributesValues.connectionCommand(queryName)); - const connectionId: string | null | undefined = dbPr.parentElement?.getAttribute(elementAttributes.id); + const connectionId: string | null | undefined = (dbPr.parentNode as Element)?.getAttribute(elementAttributes.id); const connectionXmlFileString: string = serializer.serializeToString(connectionsDoc); if (connectionId === null) { @@ -128,7 +129,7 @@ const updateSharedStrings = (sharedStringsXmlString: string, queryName: string): let sharedStringIndex: number = textElementCollection.length; if (textElementCollection && textElementCollection.length) { for (let i = 0; i < textElementCollection.length; i++) { - if (textElementCollection[i].innerHTML === queryName) { + if (textElementCollection[i].textContent === queryName) { textElement = textElementCollection[i]; sharedStringIndex = i + 1; break; diff --git a/src/utils/xmlPartsUtils.ts b/src/utils/xmlPartsUtils.ts index 36fd306..8f792e6 100644 --- a/src/utils/xmlPartsUtils.ts +++ b/src/utils/xmlPartsUtils.ts @@ -28,7 +28,7 @@ const updateWorkbookDataAndConfigurations = async (zip: JSZip, fileConfigs?: Fil }; const updateWorkbookPowerQueryDocument = async (zip: JSZip, queryName: string, queryMashupDoc: string): Promise => { - const old_base64: string | undefined = await pqUtils.getBase64(zip); + const old_base64: string | null = await pqUtils.getBase64(zip); if (!old_base64) { throw new Error(base64NotFoundErr);