UNPKG

xml-disassembler

Version:

Disassemble XML files into smaller, more manageable files and reassemble the XML when needed.

3 lines (2 loc) 12.8 kB
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("log4js"),require("node:fs/promises"),require("node:path/posix"),require("node:fs"),require("node:path"),require("ignore"),require("fast-xml-parser"),require("json5"),require("smol-toml"),require("ini"),require("yaml"),require("node:crypto"),require("fs/promises")):"function"==typeof define&&define.amd?define(["exports","log4js","node:fs/promises","node:path/posix","node:fs","node:path","ignore","fast-xml-parser","json5","smol-toml","ini","yaml","node:crypto","fs/promises"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).jsTemplate={},e.log4js,e.promises,e.posix,e.node_fs,e.node_path,e.ignore,e.fastXmlParser,e.json5,e.smolToml,e.ini,e.yaml,e.node_crypto,e.promises$1)}(this,function(e,t,n,r,i,o,s,l,a,u,d,c,f,m){"use strict";function y(e,t,n,r){return new(n||(n=Promise))(function(i,o){function s(e){try{a(r.next(e))}catch(e){o(e)}}function l(e){try{a(r.throw(e))}catch(e){o(e)}}function a(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(s,l)}a((r=r.apply(e,t||[])).next())})}function p(e,t){for(const[n,r]of Object.entries(t))Array.isArray(r)?h(e,n,r):v(r)?g(e,n,r):b(e,n,r)}function h(e,t,n){e[t]?Array.isArray(e[t])?e[t].push(...n):e[t]=[e[t],...n]:e[t]=n}function g(e,t,n){Array.isArray(e[t])?e[t].push(n):e[t]?e[t]=[e[t],n]:e[t]=n}function b(e,t,n){Object.prototype.hasOwnProperty.call(e,t)||(e[t]=n)}function v(e){return"object"==typeof e&&null!==e}"function"==typeof SuppressedError&&SuppressedError;const P={commentPropName:"!---",ignoreAttributes:!1,ignoreNameSpace:!1,parseTagValue:!1,parseNodeValue:!1,parseAttributeValue:!1,trimValues:!1,processEntities:!1,cdataPropName:"![CDATA["},j=Object.assign(Object.assign({},P),{format:!0,indentBy:" ",suppressBooleanAttributes:!1,suppressEmptyNode:!1});function E(e,t){return"#text"===e&&"string"==typeof t&&""===t.trim()}function x(e){return Array.isArray(e)?e.map(x).filter(e=>!("object"==typeof e&&0===Object.keys(e).length)):"object"==typeof e&&null!==e?function(e){const t={};for(const n in e){const r=e[n];if(E(n,r))continue;const i=x(r);void 0!==i&&(t[n]=i)}return t}(e):e}let N=null;function q(e){return y(this,void 0,void 0,function*(){const t=(N||(N=new l.XMLParser(P)),N);let r;try{const i=yield n.readFile(e,"utf-8");r=t.parse(i,!0);return x(r)}catch(t){return void J.error(`${e} was unabled to be parsed and will not be processed. Confirm formatting and try again.`)}})}const A={".yaml":c.parse,".yml":c.parse,".json":JSON.parse,".json5":a.parse,".toml":u.parse,".ini":d.parse};function F(e){return y(this,void 0,void 0,function*(){if(e.endsWith(".xml"))return yield q(e);const t=Object.keys(A).find(t=>e.endsWith(t)),n=yield m.readFile(e,"utf-8");return A[t](n)})}let O=null;function w(e){return(O||(O=new l.XMLBuilder(j)),O).build(e).trimEnd()}function C(e){return y(this,void 0,void 0,function*(){return c.stringify(e)})}function D(e){return y(this,void 0,void 0,function*(){return a.stringify(e,null,2)})}function $(e){return y(this,void 0,void 0,function*(){return JSON.stringify(e,null,2)})}function _(e){return y(this,void 0,void 0,function*(){return u.stringify(e)})}function I(e){return y(this,void 0,void 0,function*(){return d.stringify(e)})}const k={yaml:C,json5:D,json:$,toml:_,ini:I};const T=new WeakMap;function L(e,t){var n,r;if(!t)return M(e);return null!==(r=null!==(n=function(e,t){for(const n of t){const t=e[n];if("string"==typeof t)return t}}(e,t.split(",")))&&void 0!==n?n:function(e,t){for(const n in e){const r=e[n];if(!X(r))continue;const i=L(r,t);if(i)return i}}(e,t))&&void 0!==r?r:M(e)}function X(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function M(e){let t=T.get(e);t||(t=JSON.stringify(e),T.set(e,t));return f.createHash("sha256").update(t).digest("hex").slice(0,8)}function S(e){return y(this,arguments,void 0,function*({content:e,disassembledPath:t,outputFileName:i,subdirectory:o,wrapKey:s,isGroupedArray:l=!1,rootElementName:a,rootAttributes:u,xmlDeclaration:d,format:c,uniqueIdElements:f}){const m=o?r.join(t,o):t;let y=i;if(!y&&s&&!l&&"object"==typeof e){y=`${L(e,f)}.${s}-meta.${c}`}const p=r.join(m,y);yield n.mkdir(m,{recursive:!0});let h={[a]:Object.assign(Object.assign({},u),s?{[s]:e}:e)};"object"==typeof d&&null!==d&&(h=Object.assign({"?xml":d},h));const g=function(e){return k[e]}(c),b=g?yield g(h):w(h);yield n.writeFile(p,b),J.debug(`Created disassembled file: ${p}`)})}function G(e){return y(this,void 0,void 0,function*(){const{element:t,disassembledPath:n,uniqueIdElements:r,rootElementName:i,rootAttributes:o,key:s,leafCount:l,hasNestedElements:a,format:u,xmlDeclaration:d,strategy:c}=e,f=Array.isArray(t),m="object"==typeof t&&null!==t&&Object.keys(t).some(e=>!e.startsWith("#"));return f||m?"grouped-by-tag"===c?{leafContent:{},leafCount:l,hasNestedElements:!0,nestedGroups:{[s]:[t]}}:(yield S({content:t,disassembledPath:n,subdirectory:s,wrapKey:s,rootElementName:i,rootAttributes:o,xmlDeclaration:d,format:u,uniqueIdElements:r}),{leafContent:{},leafCount:l,hasNestedElements:!0}):{leafContent:{[s]:[t]},leafCount:l+1,hasNestedElements:a}})}function B(e){return y(this,arguments,void 0,function*({filePath:e,disassembledPath:t,baseName:r,postPurge:i,format:o,uniqueIdElements:s,strategy:l}){const a=yield q(e);if(!a)return;const{rootElementName:u,rootElement:d,xmlDeclaration:c}=function(e){const t=e["?xml"],n="object"==typeof t&&null!==t?t:void 0,r=Object.keys(e).find(e=>"?xml"!==e),i=e[r];return{rootElementName:r,rootElement:i,xmlDeclaration:n}}(a),f=function(e){const t={};for(const[n,r]of Object.entries(e))n.startsWith("@")&&"string"==typeof r&&(t[n]=r);return t}(d),m=Object.keys(d).filter(e=>!e.startsWith("@")),{leafContent:p,nestedGroups:h,leafCount:g,hasNestedElements:b}=yield function(e){return y(this,arguments,void 0,function*({rootElement:e,keyOrder:t,disassembledPath:n,rootElementName:r,rootAttributes:i,xmlDeclaration:o,uniqueIdElements:s,strategy:l,format:a}){var u,d;let c={},f={},m=0,y=!1;const p=20;for(const h of t){const t=Array.isArray(e[h])?e[h]:[e[h]];for(let e=0;e<t.length;e+=p){const g=t.slice(e,e+p),b=yield Promise.all(g.map((e,t)=>G({element:e,disassembledPath:n,uniqueIdElements:s,rootElementName:r,rootAttributes:i,key:h,leafCount:m,hasNestedElements:y,format:a,xmlDeclaration:o,strategy:l})));for(let e=0;e<b.length;e++){const t=b[e];if(t.leafContent[h]&&(c[h]=[...null!==(u=c[h])&&void 0!==u?u:[],...t.leafContent[h]]),"grouped-by-tag"===l&&t.nestedGroups)for(const e in t.nestedGroups)f[e]=[...null!==(d=f[e])&&void 0!==d?d:[],...t.nestedGroups[e]];m=t.leafCount,y=t.hasNestedElements}}}return{leafContent:c,nestedGroups:f,leafCount:m,hasNestedElements:y}})}({rootElement:d,keyOrder:m,disassembledPath:t,rootElementName:u,rootAttributes:f,xmlDeclaration:c,uniqueIdElements:s,strategy:l,format:o});(function(e,t,n){if(!t&&e>0)return J.error(`The XML file ${n} only has leaf elements. This file will not be disassembled.`),!0;return!1})(g,b,e)||(yield function(e,t,n){return y(this,void 0,void 0,function*(){if("grouped-by-tag"===t)for(const t in e)yield S({content:e[t],disassembledPath:n.disassembledPath,outputFileName:`${t}.${n.format}`,wrapKey:t,isGroupedArray:!0,rootElementName:n.rootElementName,rootAttributes:n.rootAttributes,xmlDeclaration:n.xmlDeclaration,format:n.format})})}(h,l,{disassembledPath:t,rootElementName:u,rootAttributes:f,xmlDeclaration:c,format:o}),yield function(e){return y(this,arguments,void 0,function*({leafCount:e,leafContent:t,strategy:n,keyOrder:r,options:i}){if(0===e)return;const o="grouped-by-tag"===n?function(e,t){const n={};for(const r of t)void 0!==e[r]&&(n[r]=e[r]);return n}(t,r):t;yield S(Object.assign({content:o},i))})}({leafCount:g,leafContent:p,strategy:l,keyOrder:m,options:{disassembledPath:t,outputFileName:`${r}.${o}`,rootElementName:u,rootAttributes:f,xmlDeclaration:c,format:o}}),i&&(yield n.unlink(e)))})}class W{constructor(e=10){this.queue=[],this.running=0,this.concurrency=e}add(e){return y(this,void 0,void 0,function*(){return new Promise((t,n)=>{this.queue.push(()=>y(this,void 0,void 0,function*(){try{const n=yield e();t(n)}catch(e){n(e)}})),this.process()})})}process(){return y(this,void 0,void 0,function*(){if(this.running>=this.concurrency||0===this.queue.length)return;this.running++;const e=this.queue.shift();try{yield e()}finally{this.running--,this.process()}})}waitForCompletion(){return y(this,void 0,void 0,function*(){for(;this.running>0||this.queue.length>0;)yield new Promise(e=>setTimeout(e,10))})}}const J=t.getLogger();t.configure({appenders:{disassemble:{type:"file",filename:"disassemble.log"}},categories:{default:{appenders:["disassemble"],level:"error"}}}),e.DisassembleXMLFileHandler=class{constructor(){this.ign=s(),this.taskQueue=new W(10)}disassemble(e){return y(this,void 0,void 0,function*(){let{filePath:t,uniqueIdElements:r,strategy:i="unique-id",prePurge:s=!1,postPurge:l=!1,ignorePath:a=".xmldisassemblerignore",format:u="xml"}=e;["unique-id","grouped-by-tag"].includes(i)||(J.warn(`Unsupported strategy "${i}", defaulting to "unique-id".`),i="unique-id"),yield this._loadIgnoreRules(a);const d=yield n.stat(t),c=this.posixPath(o.relative(process.cwd(),t));d.isFile()?yield this._handleFile(t,c,{uniqueIdElements:r,strategy:i,prePurge:s,postPurge:l,format:u}):d.isDirectory()&&(yield this._handleDirectory(t,{uniqueIdElements:r,strategy:i,prePurge:s,postPurge:l,format:u,ignorePath:a}))})}_loadIgnoreRules(e){return y(this,void 0,void 0,function*(){const t=o.resolve(e);if(i.existsSync(t)){const e=yield n.readFile(t);this.ign.add(e.toString())}})}_handleFile(e,t,n){return y(this,void 0,void 0,function*(){const r=o.resolve(e);if(!this._isXmlFile(r))return void J.error(`The file path provided is not an XML file: ${r}`);if(this.ign.ignores(t))return void J.warn(`File ignored by ignore rules: ${r}`);const i=o.dirname(r);yield this.processFile(Object.assign(Object.assign({},n),{dirPath:i,filePath:r}))})}_handleDirectory(e,t){return y(this,void 0,void 0,function*(){const r=(yield n.readdir(e)).map(n=>y(this,void 0,void 0,function*(){const r=o.join(e,n),i=this.posixPath(o.relative(process.cwd(),r));if(this._isXmlFile(r)&&!this.ign.ignores(i))return this.taskQueue.add(()=>this.processFile(Object.assign(Object.assign({},t),{dirPath:e,filePath:r})));this.ign.ignores(i)&&J.warn(`File ignored by ignore rules: ${r}`)}));yield Promise.all(r)})}_isXmlFile(e){return e.endsWith(".xml")}processFile(e){return y(this,void 0,void 0,function*(){const{dirPath:t,strategy:r,filePath:s,uniqueIdElements:l,prePurge:a,postPurge:u,format:d}=e;J.debug(`Parsing file to disassemble: ${s}`);const c=o.basename(s,o.extname(s)),f=c.split(".")[0],m=o.join(t,f);a&&i.existsSync(m)&&(yield n.rm(m,{recursive:!0})),yield B({filePath:s,disassembledPath:m,uniqueIdElements:l,baseName:c,postPurge:u,format:d,strategy:r})})}posixPath(e){return e.replace(/\\+/g,"/")}},e.ReassembleXMLFileHandler=class{reassemble(e){return y(this,void 0,void 0,function*(){const{filePath:t,fileExtension:r,postPurge:i=!1}=e;if(!(yield this._validateDirectory(t)))return;J.debug(`Parsing directory to reassemble: ${t}`);const o=yield this.processFilesInDirectory(t);if(!o.length)return void this._logEmptyParseError(t);const s=w(function(e){if(0===e.length)return void J.error("No elements to merge.");const t=e[0],n=Object.keys(t).find(e=>"?xml"!==e),r={};for(const t of e)p(r,t[n]);return function(e,t,n){return e?{"?xml":e,[t]:n}:{[t]:n}}(t["?xml"],n,r)}(o)),l=this._getOutputPath(t,r);yield n.writeFile(l,s,"utf-8"),i&&(yield n.rm(t,{recursive:!0}))})}processFilesInDirectory(e){return y(this,void 0,void 0,function*(){const t=[],i=yield n.readdir(e),o=this._sortFilesByBaseName(i).map(t=>n.stat(r.join(e,t)).then(e=>({file:t,stats:e}))),s=yield Promise.all(o);for(const{file:n,stats:i}of s){const o=r.join(e,n);if(i.isFile()&&this._isParsableFile(n)){const e=yield F(o);e&&t.push(e)}else if(i.isDirectory()){const e=yield this.processFilesInDirectory(o);t.push(...e)}}return t})}_sortFilesByBaseName(e){return e.sort((e,t)=>e.split(".")[0].localeCompare(t.split(".")[0]))}_isParsableFile(e){return/\.(xml|json|json5|ya?ml|toml|ini)$/i.test(e)}_validateDirectory(e){return y(this,void 0,void 0,function*(){return!!(yield n.stat(e)).isDirectory()||(J.error(`The provided path to reassemble is not a directory: ${e}`),!1)})}_logEmptyParseError(e){J.error(`No files under ${e} were parsed successfully. A reassembled XML file was not created.`)}_getOutputPath(e,t){const n=r.dirname(e),i=`${r.basename(e)}.${null!=t?t:"xml"}`;return r.join(n,i)}},e.buildXMLString=w,e.logger=J,e.parseXML=q,e.setLogLevel=function(e){t.getLogger().level=e},e.transformToIni=I,e.transformToJson=$,e.transformToJson5=D,e.transformToToml=_,e.transformToYaml=C}); //# sourceMappingURL=index.min.umd.js.map