diff --git a/packages/salesforce/src/deploymentPackage.ts b/packages/salesforce/src/deploymentPackage.ts
index 6b6310e8..25138c56 100644
--- a/packages/salesforce/src/deploymentPackage.ts
+++ b/packages/salesforce/src/deploymentPackage.ts
@@ -541,7 +541,7 @@ export class SalesforcePackage {
private normalizeDataForPackage(packagePath: string, data: Buffer | string) {
if (XML.isXml(data)) {
// Normalize all XML data to avoid SF deployment errors due to excess spaces
- return XML.normalize(data);
+ return XML.normalize(data, { indent: 4, headless: false });
}
return data;
}
diff --git a/packages/util/src/__tests__/xml.test.ts b/packages/util/src/__tests__/xml.test.ts
index 8c1f2e45..ce1d5466 100644
--- a/packages/util/src/__tests__/xml.test.ts
+++ b/packages/util/src/__tests__/xml.test.ts
@@ -36,7 +36,7 @@ describe('xml', () => {
$: { attr: '&>' },
'#text': `I&D '100' > '200'`
}
- }, undefined, { headless: true })).toBe(xmlStr);
+ }, { headless: true })).toBe(xmlStr);
});
});
describe('#parse', () => {
@@ -130,6 +130,14 @@ describe('xml', () => {
'test.tag.bar|2'))).toEqual('bar2');
});
});
+ describe('#normalize', () => {
+ it('should retain boolean attributes', () => {
+ const xml = ``
+ const expected = ``;
+ const actual = XML.normalize(xml, { headless: true });
+ expect(actual).toEqual(expected);
+ });
+ });
describe('#getNodeTextRange', () => {
it('should get node text range on multiple lines', () => {
const xml = `
@@ -157,7 +165,7 @@ describe('xml', () => {
it('should get node text range of root node', () => {
const xml = `
barbar`
- expect(XML.getNodeTextRange(xml, 'test')).toEqual( {
+ expect(XML.getNodeTextRange(xml, 'test')).toEqual({
start: { line: 2, column: 13 },
end: { line: 2, column: 65 }
});
diff --git a/packages/util/src/xml.ts b/packages/util/src/xml.ts
index f5d40aa1..f0d40083 100644
--- a/packages/util/src/xml.ts
+++ b/packages/util/src/xml.ts
@@ -42,6 +42,7 @@ export interface XMLParseOptions {
export interface XMLStringfyOptions {
trimValues?: boolean;
headless?: boolean;
+ indent?: string | number;
stripEmptyNodes?: boolean;
}
@@ -58,14 +59,15 @@ export interface TextRange {
export namespace XML {
const options: Partial = {
- attributeNamePrefix : '',
+ attributeNamePrefix: '',
attributesGroupName: '$',
- textNodeName : '#text',
+ textNodeName: '#text',
cdataPropName: '__cdata', // default is 'false'
ignoreAttributes : false,
- allowBooleanAttributes : true,
- parseAttributeValue : true,
- removeNSPrefix : false,
+ allowBooleanAttributes: true,
+ suppressBooleanAttributes: false,
+ parseAttributeValue: true,
+ removeNSPrefix: false,
trimValues: true,
ignoreDeclaration: false,
ignorePiTags: true,
@@ -146,15 +148,24 @@ export namespace XML {
* @param indent Indent level; if set pretty prints the XML otherwise omits pretty prtining
* @returns
*/
- export function stringify(jsonObj: any, indent?: number | string, options: XMLStringfyOptions = {}) : string {
- const indentOptions: Partial = {
- format: indent !== undefined,
- suppressEmptyNode: options.stripEmptyNodes,
- indentBy: indent !== undefined ? typeof indent === 'string' ? indent : ' '.repeat(indent) : undefined,
+ export function stringify(jsonObj: any, options?: XMLStringfyOptions) : string;
+ export function stringify(jsonObj: any, indent?: number | string, options?: XMLStringfyOptions) : string;
+ export function stringify(jsonObj: any, indent?: number | string | XMLStringfyOptions, options?: XMLStringfyOptions) : string {
+ options = typeof indent === 'object' ? indent : options;
+ indent = typeof indent === 'object' ? undefined : (options?.indent ?? indent);
+ const indentBy = (indent && typeof indent !== 'object')
+ ? (typeof indent === 'string' ? indent : ' '.repeat(indent))
+ : undefined;
+
+ const builderOptions: Partial = {
+ format: !!indentBy,
+ suppressEmptyNode: options?.stripEmptyNodes === true,
+ indentBy
};
- const xmlString = new XMLBuilder({ ...globalStringifyOptions, ...indentOptions }).build(jsonObj);
+
+ const xmlString = new XMLBuilder({ ...globalStringifyOptions, ...builderOptions }).build(jsonObj);
if (options?.headless !== true) {
- return `\n${xmlString}`;
+ return `${builderOptions.format ? '\n' : ''}${xmlString}`;
}
return xmlString;
}
@@ -193,8 +204,8 @@ export namespace XML {
* @param xml XML string or buffer
* @returns normalized XML string without comments or line-breaks.
*/
- export function normalize(xml: string | Buffer) {
- return stringify(parse(xml, { trimValues: true }));
+ export function normalize(xml: string | Buffer, options?: XMLStringfyOptions) {
+ return stringify(parse(xml, { trimValues: true }), 0, options);
}
/**