Skip to content

Commit

Permalink
fix: XML metadata with boolean attributes is not deployed correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
Codeneos committed Aug 1, 2023
1 parent 709e035 commit 7389674
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 17 deletions.
2 changes: 1 addition & 1 deletion packages/salesforce/src/deploymentPackage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
12 changes: 10 additions & 2 deletions packages/util/src/__tests__/xml.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('xml', () => {
$: { attr: '&>' },
'#text': `I&D '100' > '200'`
}
}, undefined, { headless: true })).toBe(xmlStr);
}, { headless: true })).toBe(xmlStr);
});
});
describe('#parse', () => {
Expand Down Expand Up @@ -130,6 +130,14 @@ describe('xml', () => {
'test.tag.bar|2'))).toEqual('<bar>bar2</bar>');
});
});
describe('#normalize', () => {
it('should retain boolean attributes', () => {
const xml = `<value xsi:nil="true"/>`
const expected = `<value xsi:nil="true"></value>`;
const actual = XML.normalize(xml, { headless: true });
expect(actual).toEqual(expected);
});
});
describe('#getNodeTextRange', () => {
it('should get node text range on multiple lines', () => {
const xml = `<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
Expand Down Expand Up @@ -157,7 +165,7 @@ describe('xml', () => {
it('should get node text range of root node', () => {
const xml = `<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<test><tag><bar>bar</bar></tag><bar>bar</bar></test>`
expect(XML.getNodeTextRange(xml, 'test')).toEqual( {
expect(XML.getNodeTextRange(xml, 'test')).toEqual({
start: { line: 2, column: 13 },
end: { line: 2, column: 65 }
});
Expand Down
39 changes: 25 additions & 14 deletions packages/util/src/xml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export interface XMLParseOptions {
export interface XMLStringfyOptions {
trimValues?: boolean;
headless?: boolean;
indent?: string | number;
stripEmptyNodes?: boolean;
}

Expand All @@ -58,14 +59,15 @@ export interface TextRange {
export namespace XML {

const options: Partial<X2jOptions & XmlBuilderOptions> = {
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,
Expand Down Expand Up @@ -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<XmlBuilderOptions> = {
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<XmlBuilderOptions> = {
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 `<?xml version="1.0" encoding="UTF-8"?>\n${xmlString}`;
return `<?xml version="1.0" encoding="UTF-8"?>${builderOptions.format ? '\n' : ''}${xmlString}`;
}
return xmlString;
}
Expand Down Expand Up @@ -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);
}

/**
Expand Down

0 comments on commit 7389674

Please sign in to comment.