2021-03-11 01:06:55 +00:00
|
|
|
import { BaseXmlComponent, IContext } from "./base";
|
2017-09-19 15:46:20 +01:00
|
|
|
import { IXmlableObject } from "./xmlable-object";
|
|
|
|
|
2019-04-10 13:47:38 -04:00
|
|
|
export const EMPTY_OBJECT = Object.seal({});
|
|
|
|
|
2017-09-19 15:46:20 +01:00
|
|
|
export abstract class XmlComponent extends BaseXmlComponent {
|
2019-12-18 21:11:15 +00:00
|
|
|
// tslint:disable-next-line:readonly-keyword no-any
|
2020-08-01 17:58:16 +01:00
|
|
|
protected root: (BaseXmlComponent | string | any)[];
|
2017-09-19 15:46:20 +01:00
|
|
|
|
2018-09-17 20:22:11 +01:00
|
|
|
constructor(rootKey: string) {
|
2017-09-19 15:46:20 +01:00
|
|
|
super(rootKey);
|
2018-09-20 00:41:57 +01:00
|
|
|
this.root = new Array<BaseXmlComponent | string>();
|
2017-09-19 15:46:20 +01:00
|
|
|
}
|
|
|
|
|
2021-03-11 01:06:55 +00:00
|
|
|
public prepForXml(context: IContext): IXmlableObject | undefined {
|
2018-01-23 01:33:12 +00:00
|
|
|
const children = this.root
|
|
|
|
.map((comp) => {
|
|
|
|
if (comp instanceof BaseXmlComponent) {
|
2021-03-11 01:06:55 +00:00
|
|
|
return comp.prepForXml(context);
|
2018-01-23 01:33:12 +00:00
|
|
|
}
|
|
|
|
return comp;
|
|
|
|
})
|
2018-09-20 00:41:57 +01:00
|
|
|
.filter((comp) => comp !== undefined); // Exclude undefined
|
2019-04-09 05:27:18 -04:00
|
|
|
// If we only have a single IXmlableObject in our children array and it
|
|
|
|
// represents our attributes, use the object itself as our children to
|
2021-05-22 03:47:10 +03:00
|
|
|
// avoid an unneeded XML close element.
|
2019-04-10 01:28:37 -04:00
|
|
|
// Additionally, if the array is empty, use an empty object as our
|
|
|
|
// children in order to get an empty XML element generated.
|
2017-09-19 15:46:20 +01:00
|
|
|
return {
|
2021-05-22 03:47:10 +03:00
|
|
|
[this.rootKey]: children.length ? (children.length === 1 && children[0]?._attr ? children[0] : children) : EMPTY_OBJECT,
|
2017-09-19 15:46:20 +01:00
|
|
|
};
|
|
|
|
}
|
2018-04-23 11:49:57 +02:00
|
|
|
|
2018-05-06 03:19:36 +01:00
|
|
|
public addChildElement(child: XmlComponent | string): XmlComponent {
|
2018-04-23 11:49:57 +02:00
|
|
|
this.root.push(child);
|
2018-05-06 03:19:36 +01:00
|
|
|
|
|
|
|
return this;
|
2018-04-23 11:49:57 +02:00
|
|
|
}
|
2017-09-19 15:46:20 +01:00
|
|
|
}
|
2019-04-09 05:27:18 -04:00
|
|
|
|
|
|
|
export abstract class IgnoreIfEmptyXmlComponent extends XmlComponent {
|
2021-03-11 01:06:55 +00:00
|
|
|
public prepForXml(context: IContext): IXmlableObject | undefined {
|
|
|
|
const result = super.prepForXml(context);
|
2019-04-10 01:28:37 -04:00
|
|
|
// Ignore the object if its falsey or is an empty object (would produce
|
|
|
|
// an empty XML element if allowed to be included in the output).
|
|
|
|
if (result && (typeof result[this.rootKey] !== "object" || Object.keys(result[this.rootKey]).length)) {
|
2019-04-09 05:27:18 -04:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|