Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

T shanim/randomize workbook uuids #81

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const formulaSectionNotFoundErr = "Formula section wasn't found in templa
export const templateWithInitialDataErr = "Cannot receive template file with initial data";
export const queryTableNotFoundErr = "Query table wasn't found in template";
export const tableNotFoundErr = "Table wasn't found in template";
export const workbookNotFoundErr = "Workbook wasn't found in template";
export const invalidValueInColumnErr = "Invalid cell value in column";
export const headerNotFoundErr = "Invalid JSON file, header is missing";
export const invalidDataTypeErr = "Invalid JSON file, invalid data type";
Expand Down Expand Up @@ -81,6 +82,9 @@ export const element = {
dimension: "dimension",
selection: "selection",
kindCell: "c",
connection: "connection",
worksheet: "worksheet",
workbookView: "workbookView"
};

export const elementAttributes = {
Expand Down Expand Up @@ -113,6 +117,9 @@ export const elementAttributes = {
spans: "spans",
x14acDyDescent: "x14ac:dyDescent",
xr3uid: "xr3:uid",
xr2uid: "xr2:uid",
xr16uid: "xr16:uid",
xruid: "xr:uid",
};

export const dataTypeKind = {
Expand Down
69 changes: 68 additions & 1 deletion src/utils/xmlInnerPartsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
emptyValue,
} from "./constants";
import documentUtils from "./documentUtils";
import { v4 } from "uuid";

const updateDocProps = async (zip: JSZip, docProps: DocProps = {}): Promise<void> => {
const { doc, properties } = await documentUtils.getDocPropsProperties(zip);
Expand Down Expand Up @@ -131,7 +132,8 @@ const updateWorksheet = (sheetsXmlString: string, sharedStringIndex: string): st
const parser: DOMParser = new DOMParser();
const serializer: XMLSerializer = new XMLSerializer();
const sheetsDoc: Document = parser.parseFromString(sheetsXmlString, xmlTextResultType);
sheetsDoc.getElementsByTagName(element.cellValue)[0].innerHTML = sharedStringIndex.toString();
const cellValue: Element = sheetsDoc.getElementsByTagName(element.cellValue)[0];
cellValue.innerHTML = sharedStringIndex;
const newSheet: string = serializer.serializeToString(sheetsDoc);

return newSheet;
Expand Down Expand Up @@ -235,6 +237,66 @@ const updatePivotTable = (tableXmlString: string, connectionId: string, refreshO
return { isPivotTableUpdated, newPivotTable };
};

const randomizeConnectionsUUID = (connectionsXmlString: string): string => {
const parser: DOMParser = new DOMParser();
const serializer: XMLSerializer = new XMLSerializer();
const connectionsDoc: Document = parser.parseFromString(connectionsXmlString, xmlTextResultType);
const connection: Element = connectionsDoc.getElementsByTagName(element.connection)[0];
connection.setAttribute(elementAttributes.xr16uid, "{" + v4().toUpperCase() + "}");
const newConnections: string = serializer.serializeToString(connectionsDoc);

return newConnections;
};

const randomizeWorksheetUUID = (worksheetXmlString: string): string => {
const parser: DOMParser = new DOMParser();
const serializer: XMLSerializer = new XMLSerializer();
const worksheetDoc: Document = parser.parseFromString(worksheetXmlString, xmlTextResultType);
const worksheet: Element = worksheetDoc.getElementsByTagName(element.worksheet)[0];
worksheet.setAttribute(elementAttributes.xruid, "{" + v4().toUpperCase() + "}");
const newSheet: string = serializer.serializeToString(worksheetDoc);

return newSheet;
};

const randomizeTableUUID = (tableXmlString: string): string => {
const parser: DOMParser = new DOMParser();
const serializer: XMLSerializer = new XMLSerializer();
const tableDoc: Document = parser.parseFromString(tableXmlString, xmlTextResultType);
const table: Element = tableDoc.getElementsByTagName(element.table)[0];
const tableUUID: string = "{" + v4().toUpperCase() + "}";
table.setAttribute(elementAttributes.xruid, tableUUID);
const autoFilter: Element = tableDoc.getElementsByTagName(element.autoFilter)[0];
autoFilter.setAttribute(elementAttributes.xruid, tableUUID);
const tableColumn: Element = tableDoc.getElementsByTagName(element.tableColumn)[0];
tableColumn.setAttribute(elementAttributes.xr3uid, "{" + v4().toUpperCase() + "}");
const newTable: string = serializer.serializeToString(tableDoc);

return newTable;
};

const randomizeQueryTableUUID = (queryTableXmlString: string): string => {
const parser: DOMParser = new DOMParser();
const serializer: XMLSerializer = new XMLSerializer();
const queryTableDoc: Document = parser.parseFromString(queryTableXmlString, xmlTextResultType);
const queryTable: Element = queryTableDoc.getElementsByTagName(element.queryTable)[0];
queryTable.setAttribute(elementAttributes.xr16uid, "{" + v4().toUpperCase() + "}");
const newQueryTable: string = serializer.serializeToString(queryTableDoc);

return newQueryTable;
};

const randomizeWorkbookUUID = (workbookXmlString: string): string => {
const parser: DOMParser = new DOMParser();
const serializer: XMLSerializer = new XMLSerializer();
const workbookDoc: Document = parser.parseFromString(workbookXmlString, xmlTextResultType);
const workbookView: Element = workbookDoc.getElementsByTagName(element.workbookView)[0];
workbookView.setAttribute(elementAttributes.xr2uid, "{" + v4().toUpperCase() + "}");
const newWorkbook: string = serializer.serializeToString(workbookDoc);

return newWorkbook;
};

export default {
updateDocProps,
updateConnections,
Expand All @@ -243,4 +305,9 @@ export default {
updatePivotTablesandQueryTables,
updateQueryTable,
updatePivotTable,
randomizeConnectionsUUID,
randomizeWorksheetUUID,
randomizeTableUUID,
randomizeQueryTableUUID,
randomizeWorkbookUUID
};
51 changes: 51 additions & 0 deletions src/utils/xmlPartsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ import {
sharedStringsNotFoundErr,
sheetsXmlPath,
sheetsNotFoundErr,
tableXmlPath,
queryTableXmlPath,
queryTableNotFoundErr,
workbookXmlPath,
workbookNotFoundErr,
tableNotFoundErr,
} from "./constants";
import { replaceSingleQuery } from "./mashupDocumentParser";
import { DocProps, TableData } from "../types";
Expand Down Expand Up @@ -66,8 +72,53 @@ const updateWorkbookSingleQueryAttributes = async (zip: JSZip, queryName: string
await xmlInnerPartsUtils.updatePivotTablesandQueryTables(zip, queryName, refreshOnOpen, connectionId!);
};

const updateWorkbookGeneratedUUIDs = async (zip: JSZip, updateQueryTable: boolean = false): Promise<void> => {
const sheetsXmlString: string | undefined = await zip.file(sheetsXmlPath)?.async(textResultType);
if (sheetsXmlString === undefined) {
throw new Error(sheetsNotFoundErr);
}

const sheetString: string = xmlInnerPartsUtils.randomizeWorksheetUUID(sheetsXmlString);
zip.file(sheetsXmlPath, sheetString);

const workbookXmlString: string | undefined = await zip.file(workbookXmlPath)?.async(textResultType);
if (workbookXmlString === undefined) {
throw new Error(workbookNotFoundErr);
}

const workbookString: string = xmlInnerPartsUtils.randomizeWorkbookUUID(workbookXmlString);
zip.file(workbookXmlPath, workbookString);

const tableXmlString: string | undefined = await zip.file(tableXmlPath)?.async(textResultType);
if (tableXmlString === undefined) {
throw new Error(tableNotFoundErr);
}

const tableString: string = xmlInnerPartsUtils.randomizeTableUUID(tableXmlString);
zip.file(tableXmlPath, tableString);

if (updateQueryTable) {
const connectionsXmlString: string | undefined = await zip.file(connectionsXmlPath)?.async(textResultType);
if (connectionsXmlString === undefined) {
throw new Error(connectionsNotFoundErr);
}

const connectionXmlFileString = xmlInnerPartsUtils.randomizeConnectionsUUID(connectionsXmlString);
zip.file(connectionsXmlPath, connectionXmlFileString);

const queryTableXmlString: string | undefined = await zip.file(queryTableXmlPath)?.async(textResultType);
if (queryTableXmlString === undefined) {
throw new Error(queryTableNotFoundErr);
}

const queryTableString: string = xmlInnerPartsUtils.randomizeQueryTableUUID(queryTableXmlString);
zip.file(queryTableXmlPath, queryTableString);
}
};

export default {
updateWorkbookInitialDataIfNeeded,
updateWorkbookPowerQueryDocument,
updateWorkbookSingleQueryAttributes,
updateWorkbookGeneratedUUIDs,
};
2 changes: 2 additions & 0 deletions src/workbookManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export const generateTableWorkbookFromGrid = async (grid: Grid, docProps?: DocPr
throw new Error(tableNotFoundErr);
}

await xmlPartsUtils.updateWorkbookGeneratedUUIDs(zip);
await xmlPartsUtils.updateWorkbookInitialDataIfNeeded(zip, docProps, tableData);

return await zip.generateAsync({
Expand All @@ -57,6 +58,7 @@ const generateSingleQueryWorkbookFromZip = async (zip: JSZip, query: QueryInfo,
query.queryName = defaults.queryName;
}

await xmlPartsUtils.updateWorkbookGeneratedUUIDs(zip, true /*updateQueryTable*/);
await xmlPartsUtils.updateWorkbookPowerQueryDocument(zip, query.queryName, generateSingleQueryMashup(query.queryName, query.queryMashup));
await xmlPartsUtils.updateWorkbookSingleQueryAttributes(zip, query.queryName, query.refreshOnOpen);
await xmlPartsUtils.updateWorkbookInitialDataIfNeeded(zip, docProps, tableData, true /*updateQueryTable*/);
Expand Down