Skip to content

Commit

Permalink
fix: remove the root xml element as a reassemble flag and dynamically…
Browse files Browse the repository at this point in the history
… get it from a disassembled file in the path
  • Loading branch information
mcarvin8 committed Feb 21, 2024
1 parent 39e57cb commit 849cf3b
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 17 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ An XML with the following nested and leaf elements
</PermissionSet>
```

will be diassembled as such:
will be disassembled as such:

- Each nested element (`<recordTypeVisibilities>`, `<applicationVisibilities>`, `pageAccesses`, etc.) will be disassembled into sub-directories by the nested element name. If a unique & required ID element (`application` is the unique ID element for `<applicationVisibilities>`) is found, the disassembled file will be named using it. Otherwise, the disassembled files for nested elements will be named using the SHA-256 of the element contents.
- Each leaf element (`<description>`, `<label>`, `<userLicense>`) will be disassembled into the same file.
Expand All @@ -122,7 +122,6 @@ Import the `ReassembleXMLFileHandler` class from the package.
```typescript
/*
FLAGS
- xmlElement: XML Root Element for the final reassembled file
- xmlPath: Path to the disassembled XML files to reassemble (must be a directory)
- xmlNamespace: (Optional) Namespace for the final XML (default: None)
- fileExtension: (Optional) Desired file extension for the final XML (default: `.xml`)
Expand All @@ -132,12 +131,13 @@ import { ReassembleXMLFileHandler } from "xml-disassembler";
const handler = new ReassembleXMLFileHandler();
await handler.reassemble({
xmlPath: "test/baselines/general/HR_Admin",
xmlElement: "PermissionSet",
xmlNamespace: "http://soap.sforce.com/2006/04/metadata",
fileExtension: "permissionset-meta.xml",
});
```

_NOTE_: You should be reassembling files created by this package's `DisassembleXMLFileHandler` class for intended results. This class will assume all disassembled files in `xmlPath` have the same XML Root Element.

The reassembled XML file will be created in the parent directory of `xmlPath` and will overwrite the original file used to create the original disassembled directories, if it still exists and the `fileExtension` flag matches the original file extension.

## Template
Expand Down
64 changes: 54 additions & 10 deletions src/service/reassembleXMLFileHandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import * as fs from "node:fs/promises";
import * as path from "node:path";
import { XMLParser } from "fast-xml-parser";
import { XmlElement, XML_PARSER_OPTION } from "@src/helpers/types";
import { buildReassembledFile } from "@src/service/buildReassembledFiles";

export class ReassembleXMLFileHandler {
Expand Down Expand Up @@ -30,13 +32,48 @@ export class ReassembleXMLFileHandler {
return combinedXmlContents;
}

async processFilesForRootElement(
dirPath: string,
): Promise<string | undefined> {
const files = await fs.readdir(dirPath);
const xmlParser = new XMLParser(XML_PARSER_OPTION);

for (const file of files) {
const filePath = path.join(dirPath, file);
const fileStat = await fs.stat(filePath);

if (fileStat.isDirectory()) {
// Recursively process files in subdirectory
const result = await this.processFilesForRootElement(filePath);
if (result !== undefined) {
// Found root element name, return it
return result;
}
} else if (fileStat.isFile()) {
// Process files
const xmlContent = await fs.readFile(filePath, "utf-8");
const xmlParsed = xmlParser.parse(xmlContent) as Record<
string,
XmlElement
>;
const rootElementName = Object.keys(xmlParsed)[1];
if (rootElementName !== undefined) {
// Found root element name, return it
return rootElementName;
}
}
}

// No root element name found in any files
return undefined;
}

async reassemble(xmlAttributes: {
xmlElement: string;
xmlPath: string;
xmlNamespace?: string | undefined;
fileExtension?: string | undefined;
xmlNamespace?: string;
fileExtension?: string;
}): Promise<void> {
const { xmlElement, xmlPath, xmlNamespace, fileExtension } = xmlAttributes;
const { xmlPath, xmlNamespace, fileExtension } = xmlAttributes;
const combinedXmlContents: string[] = [];

// Process files directly inside the `xmlPath` directory
Expand All @@ -54,18 +91,25 @@ export class ReassembleXMLFileHandler {
}
}

// Process at least one XML file to get the `rootElementName`
let rootElementName = await this.processFilesForRootElement(xmlPath);

const parentDirectory = path.dirname(xmlPath); // Get the parent directory path
const subdirectoryBasename = path.basename(xmlPath);
const fileName = fileExtension
? `${subdirectoryBasename}.${fileExtension}`
: `${subdirectoryBasename}.xml`;
const filePath = path.join(parentDirectory, fileName);

await buildReassembledFile(
combinedXmlContents,
filePath,
xmlElement,
xmlNamespace,
);
if (rootElementName !== undefined) {
await buildReassembledFile(
combinedXmlContents,
filePath,
rootElementName,
xmlNamespace,
);
} else {
console.error("Root element name is undefined");
}
}
}
4 changes: 0 additions & 4 deletions test/main.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ describe("main function", () => {
const handler = new ReassembleXMLFileHandler();
await handler.reassemble({
xmlPath: "test/baselines/general/HR_Admin",
xmlElement: "PermissionSet",
xmlNamespace: "http://soap.sforce.com/2006/04/metadata",
fileExtension: "permissionset-meta.xml",
});
Expand All @@ -49,7 +48,6 @@ describe("main function", () => {
const handler = new ReassembleXMLFileHandler();
await handler.reassemble({
xmlPath: "test/baselines/cdata/VidLand_US",
xmlElement: "MarketingAppExtension",
});

// Ensure that the console.log spy was called with the correct message
Expand All @@ -69,7 +67,6 @@ describe("main function", () => {
const handler = new ReassembleXMLFileHandler();
await handler.reassemble({
xmlPath: "test/baselines/comments/Numbers-fr",
xmlElement: "GlobalValueSetTranslation",
});

// Ensure that the console.log spy was called with the correct message
Expand Down Expand Up @@ -99,7 +96,6 @@ describe("main function", () => {
const handler = new ReassembleXMLFileHandler();
await handler.reassemble({
xmlPath: "test/baselines/array-of-leafs/Dreamhouse",
xmlElement: "CustomApplication",
xmlNamespace: "http://soap.sforce.com/2006/04/metadata",
fileExtension: "app-meta.xml",
});
Expand Down

0 comments on commit 849cf3b

Please sign in to comment.