xml-class-transformer
Version:
Fluently parse XML into beautiful JS/TS classes and serialize them. GoLang's encoding/xml alternative for JS/TS world.
8 lines (7 loc) • 4.96 kB
JavaScript
/*!
* xml-class-transformer v0.1.1
* (c) Edgar Pogosyan
* Released under the MIT License.
*/
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("xml-js")):"function"==typeof define&&define.amd?define(["exports","xml-js"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self)["xml-class-transformer"]={},e.xmljs)}(this,(function(e,t){"use strict";function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=n(t);const o=new class{constructor(){this.registry=new Map}setEntityOptions(e,t){const n=this.registry.get(e);n?n.entity=t:this.registry.set(e,{entity:t,properties:new Map})}setPropertyOptions(e,t,n){const r=this.getOrCreate(e);if(n.name)for(const[o,i]of r.properties)if(i.name===n.name)throw new Error(`xml-class-transformer: can't use XML element name defined in { name: ${JSON.stringify(n.name)} } for ${e.name}#${t} since it's already used for ${e.name}#${o}. Change it to something else.`);r.properties.set(t,n)}getOrCreate(e){const t=this.registry.get(e);if(t)return t;{const t={entity:{},properties:new Map};return this.registry.set(e,t),t}}get(e){return this.registry.get(e)}};function i(e,t){var n;if([String,Number,Boolean].includes(t)){let r;const o=null===(n=function(e){var t,n;return null===(n=null===(t=e.elements)||void 0===t?void 0:t.find((e=>"text"===e.type)))||void 0===n?void 0:n.text}(e))||void 0===n?void 0:n.toString();return t===String?r=o:t===Number?r=o?parseInt(o,10):void 0:t===Boolean&&(r=o?"true"===o:void 0),r}const r=o.get(t);if(!r)throw new Error("Unknown class "+t);const s=new t;return r.properties.forEach(((t,n)=>{var r,l,c,m;if(t.attr){if(!t.name)throw new Error(`No name is specified for attribute ${n}. Specify it with @XmlProperty({ name: '...' }) decorator.`);const o=null===(r=e.attributes)||void 0===r?void 0:r[t.name];s[n]=o||void 0}else if(t.chardata)s[n]=i(e,t.type);else if(t.array)if(Array.isArray(t.type)){const r=new Map;t.type.forEach((e=>{const t=o.get(e);if(!t)throw a(e);const n=t.entity.name;if(!n)throw new Error(`No name is specified for ${e}. Specify it with @XmlEntity({ name: '...' }) decorator.`);r.set(n,e)}));const c=[...r.keys()],m=[];null===(l=e.elements)||void 0===l||l.forEach((e=>{if(e.name&&c.includes(e.name)){const t=i(e,r.get(e.name));m.push(t)}})),s[n]=m}else{const r=(null===(c=e.elements)||void 0===c?void 0:c.filter((e=>e.name===t.name)))||[],o=[];r.forEach((e=>{const n=i(e,t.type);o.push(n)})),s[n]=o}else{const r=null===(m=e.elements)||void 0===m?void 0:m.find((e=>e.name===t.name));if(r){const e=i(r,t.type);s[n]=e}else s[n]=void 0}})),s}function s(e,t,n){if([String,Number,Boolean].includes(n)){return{type:"element",name:t,elements:[{type:"text",text:null===e?"":null==e?void 0:e.toString()}]}}const r=o.get(n);if(!r)throw a(n);const i=t||r.entity.name;if(!i)throw new Error(`No name is specified for ${n}. Specify it with @XmlEntity({ name: '...' }) decorator.`);const l=[],c={};return r.properties.forEach(((t,n)=>{var r;if(void 0!==e[n])if(t.attr){if(!t.name)throw new Error(`No name is specified for property ${n}. Specify it with @XmlProperty({ name: '...' }) decorator.`);c[t.name]=null===e[n]?"":e[n].toString()}else if(t.chardata)l.push({type:"text",text:null===e[n]?"":e[n].toString()});else if(t.array)null===(r=e[n])||void 0===r||r.forEach((e=>{const n=Array.isArray(t.type)?e.constructor:t.type;l.push(s(e,t.name,n))}));else if([String,Number,Boolean].includes(t.type)){if(!t.name)throw new Error(`No name is specified for property ${n}. Specify it with @XmlProperty({ name: '...' }) decorator.`);l.push(s(e[t.name],t.name,t.type))}else l.push(s(e[n],t.name,t.type))})),r.entity.xmlns&&(c.xmlns=r.entity.xmlns),{type:"element",name:i,attributes:c,elements:l}}function a(e){return new Error(`Class ${e} not found. Make sure there is @XmlEntity({...}) decorator on it, or @XmlProperty({...}) decorator on its properties.`)}e.XmlEntity=function(e){return t=>{if((e=e||{}).name=e.name||t.name,!e.name)throw new Error(`Failed to get the element name for class ${t}. Specify it with @XmlEntity({ name: '...' }) decorator.`);return o.setEntityOptions(t,e),t}},e.XmlProperty=function(e){return(t,n)=>{if(e.name,e.name,"string"!=typeof n)throw new TypeError(`Can't use @XmlProperty({...}) decorator on symbol property at ${t.constructor.name}#${n.toString()}`);o.setPropertyOptions(t.constructor,n,e)}},e.classToXml=function(e,t){const n={elements:[s(e,"",e.constructor)]};return!1!==(null==t?void 0:t.declaration)&&("object"==typeof(null==t?void 0:t.declaration)&&null!==(null==t?void 0:t.declaration)?n.declaration=t.declaration:n.declaration={attributes:{version:"1.0",encoding:"UTF-8"}}),r.default.js2xml(n,t)},e.xmlToClass=function(e,t){var n;const o=null===(n=r.default.xml2js(e,{compact:!1,alwaysArray:!0}).elements)||void 0===n?void 0:n[0];if(!o)throw new Error("No elements found in xml.");return i(o,t)},Object.defineProperty(e,"__esModule",{value:!0})}));
//# sourceMappingURL=index.umd.min.js.map