Skip to content

Commit

Permalink
Merge pull request #10 from mcarvin8/feat/namespace
Browse files Browse the repository at this point in the history
fix: dynamically get xml namespace and add to disassembled/reassembled files if defined
  • Loading branch information
mcarvin8 authored Feb 22, 2024
2 parents 752287b + 59544ee commit 0a079e3
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 17 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,13 @@ Import the `ReassembleXMLFileHandler` class from the package.
/*
FLAGS
- 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`)
*/
import { ReassembleXMLFileHandler } from "xml-disassembler";

const handler = new ReassembleXMLFileHandler();
await handler.reassemble({
xmlPath: "test/baselines/general/HR_Admin",
xmlNamespace: "http://soap.sforce.com/2006/04/metadata",
fileExtension: "permissionset-meta.xml",
});
```
Expand Down
22 changes: 19 additions & 3 deletions src/service/buildDisassembledFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@ export function buildDisassembledFiles(
): void {
const xmlParser = new XMLParser(XML_PARSER_OPTION);
const result = xmlParser.parse(xmlString) as Record<string, XmlElement>;

const rootElementName = Object.keys(result)[1];
const rootElement: XmlElement = result[rootElementName];
let rootElementNamespace: string | undefined;
if (rootElement["@_xmlns"] !== undefined) {
rootElementNamespace = String(rootElement["@_xmlns"]);
} else {
rootElementNamespace = undefined;
}
let leafContent = "";
let leafCount = 0;

Expand All @@ -37,6 +42,7 @@ export function buildDisassembledFiles(
metadataPath,
uniqueIdElements,
rootElementName,
rootElementNamespace,
key,
indent,
);
Expand All @@ -52,6 +58,7 @@ export function buildDisassembledFiles(
metadataPath,
uniqueIdElements,
rootElementName,
rootElementNamespace,
key,
indent,
);
Expand All @@ -66,7 +73,11 @@ export function buildDisassembledFiles(

if (leafCount > 0) {
let leafFile = `${XML_HEADER}\n`;
leafFile += `<${rootElementName}>\n`;
leafFile += `<${rootElementName}`;
if (rootElementNamespace) {
leafFile += ` xmlns="${rootElementNamespace}"`;
}
leafFile += `>\n`;

const sortedLeafContent = leafContent
.split("\n") // Split by lines
Expand All @@ -87,6 +98,7 @@ function buildNestedFile(
metadataPath: string,
uniqueIdElements: string | undefined,
rootElementName: string,
rootElementNamespace: string | undefined,
parentKey: string,
indent: string,
): void {
Expand All @@ -104,7 +116,11 @@ function buildNestedFile(
// Call the buildNestedElements to build the XML content string
elementContent = buildNestedElements(element);
let decomposeFileContents = `${XML_HEADER}\n`;
decomposeFileContents += `<${rootElementName}>\n`;
decomposeFileContents += `<${rootElementName}`;
if (rootElementNamespace) {
decomposeFileContents += ` xmlns="${rootElementNamespace}"`;
}
decomposeFileContents += `>\n`;
decomposeFileContents += `${indent}<${parentKey}>\n`;
decomposeFileContents += `${elementContent}\n`;
decomposeFileContents += `${indent}</${parentKey}>\n`;
Expand Down
2 changes: 1 addition & 1 deletion src/service/buildReassembledFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export async function buildReassembledFile(
combinedXmlContents: string[],
filePath: string,
xmlElement: string,
xmlNamespace?: string | undefined,
xmlNamespace: string | undefined,
): Promise<void> {
// Combine XML contents into a single string
let finalXmlContent = combinedXmlContents.join("\n");
Expand Down
24 changes: 15 additions & 9 deletions src/service/reassembleXMLFileHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class ReassembleXMLFileHandler {

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

Expand All @@ -57,9 +57,15 @@ export class ReassembleXMLFileHandler {
XmlElement
>;
const rootElementName = Object.keys(xmlParsed)[1];
const rootElement: XmlElement = xmlParsed[rootElementName];
let rootElementNamespace: string | undefined;
if (rootElement["@_xmlns"] !== undefined) {
rootElementNamespace = String(rootElement["@_xmlns"]);
} else {
rootElementNamespace = undefined;
}
if (rootElementName !== undefined) {
// Found root element name, return it
return rootElementName;
return [rootElementName, rootElementNamespace];
}
}
}
Expand All @@ -70,10 +76,9 @@ export class ReassembleXMLFileHandler {

async reassemble(xmlAttributes: {
xmlPath: string;
xmlNamespace?: string;
fileExtension?: string;
}): Promise<void> {
const { xmlPath, xmlNamespace, fileExtension } = xmlAttributes;
const { xmlPath, fileExtension } = xmlAttributes;
const combinedXmlContents: string[] = [];
const fileStat = await fs.stat(xmlPath);

Expand All @@ -95,8 +100,8 @@ export class ReassembleXMLFileHandler {
}
}

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

const parentDirectory = path.dirname(xmlPath); // Get the parent directory path
const subdirectoryBasename = path.basename(xmlPath);
Expand All @@ -105,12 +110,13 @@ export class ReassembleXMLFileHandler {
: `${subdirectoryBasename}.xml`;
const filePath = path.join(parentDirectory, fileName);

if (rootElementName !== undefined) {
if (rootResult !== undefined) {
const [rootElementName, rootElementNamespace] = rootResult;
await buildReassembledFile(
combinedXmlContents,
filePath,
rootElementName,
xmlNamespace,
rootElementNamespace,
);
} else {
console.error("Root element name is undefined");
Expand Down
44 changes: 44 additions & 0 deletions test/baselines/no-namespace/HR_Admin.permissionset-meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<PermissionSet>
<applicationVisibilities>
<application>JobApps__Recruiting</application>
<visible>true</visible>
</applicationVisibilities>
<classAccesses>
<apexClass>Send_Email_Confirmation</apexClass>
<enabled>true</enabled>
</classAccesses>
<fieldPermissions>
<editable>true</editable>
<field>Job_Request__c.Salary__c</field>
<readable>true</readable>
</fieldPermissions>
<description>Grants all rights needed for an HR administrator to manage employees.</description>
<label>HR Administration</label>
<userLicense>Salesforce</userLicense>
<objectPermissions>
<allowCreate>true</allowCreate>
<allowDelete>true</allowDelete>
<allowEdit>true</allowEdit>
<allowRead>true</allowRead>
<viewAllRecords>true</viewAllRecords>
<modifyAllRecords>true</modifyAllRecords>
<object>Job_Request__c</object>
</objectPermissions>
<pageAccesses>
<apexPage>Job_Request_Web_Form</apexPage>
<enabled>true</enabled>
</pageAccesses>
<recordTypeVisibilities>
<recordType>Recruiting.DevManager</recordType>
<visible>true</visible>
</recordTypeVisibilities>
<tabSettings>
<tab>Job_Request__c</tab>
<visibility>Available</visibility>
</tabSettings>
<userPermissions>
<enabled>true</enabled>
<name>APIEnabled</name>
</userPermissions>
</PermissionSet>
23 changes: 21 additions & 2 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",
xmlNamespace: "http://soap.sforce.com/2006/04/metadata",
fileExtension: "permissionset-meta.xml",
});

Expand Down Expand Up @@ -96,7 +95,6 @@ describe("main function", () => {
const handler = new ReassembleXMLFileHandler();
await handler.reassemble({
xmlPath: "test/baselines/array-of-leafs/Dreamhouse",
xmlNamespace: "http://soap.sforce.com/2006/04/metadata",
fileExtension: "app-meta.xml",
});

Expand All @@ -110,6 +108,27 @@ describe("main function", () => {
purge: true,
});

// Ensure that the console.log spy was called with the correct message
expect(console.log).toHaveBeenCalled();
});
it('should disassemble a XML file with no namespace."', async () => {
const handler = new DisassembleXMLFileHandler();
await handler.disassemble({
xmlPath: "test/baselines/no-namespace",
uniqueIdElements:
"application,apexClass,name,externalDataSource,flow,object,apexPage,recordType,tab,field",
});

// Ensure that the console.log spy was called with the correct message
expect(console.log).toHaveBeenCalled();
});
it('should reassemble a XML file with no namespace."', async () => {
const handler = new ReassembleXMLFileHandler();
await handler.reassemble({
xmlPath: "test/baselines/no-namespace/HR_Admin",
fileExtension: "permissionset-meta.xml",
});

// Ensure that the console.log spy was called with the correct message
expect(console.log).toHaveBeenCalled();
});
Expand Down

0 comments on commit 0a079e3

Please sign in to comment.