@tangelo/tangelo-configuration-toolkit
Version:
Tangelo Configuration Toolkit is a command-line toolkit which offers support for developing a Tangelo configuration.
77 lines (66 loc) • 3.67 kB
JavaScript
// core
const fs = require('fs'), path = require('path');
// other
const es = require('event-stream');
const resolveImports = (fp, file) => {
let fileNew = file.replace(/<!--(?:(?!-->)[\s\S])*?-->/g, ''); // first remove all comments (so disabled includes are not resolved)
if (fileNew.includes('<x:import')) {
// replace all x:import elements by the contents of the referenced file
fileNew = fileNew.replace(/<x:import\s+src="(.*?)"\s*\/>/g, (match, g1) => {
const cmscustompath = `${path.basename(process.cwd()) != 'config' ? 'config/' : ''}cmscustom/`;
const xiPath = g1.includes('cmscustom') ? g1.replace('#{cmscustompath}', cmscustompath) : path.resolve(fp.dir, g1);
const xiFile =
fs.readFileSync(xiPath).toString()
.replace(/[\s\S]*?<x:config[^>]*>([\s\S]*?)<\/x:config>/, '$1') // only return contents of x:config element
.replace(/<(\w+)\/>/g, '<$1></$1>') // self-closing html tags can cause problems
.replace(/url="(?:\.\.\/)+pls\//g, 'url="#{plsservlet}') // replace relative references to plsservlet by bind (4.1 compatibility)
.replace(/url="(?:\.\.\/)+/g, 'url="#{cmspath}') // replace relative references to cmspath by bind (4.1 compatibility)
.replace(/(<x:javascript\s+src=")([^#].*?)("\s*\/>)/g, (match, g1, g2, g3) => { // correct all javascript refs to paths relative to cmscustompath bind
const newPath = path.resolve(fp.dir, path.resolve(path.dirname(xiPath), g2))
.replace(/.*cmscustom./, '#{cmscustompath}')
.replace(/\\/g, '/')
;
return [g1, newPath, g3].join('');
})
;
return resolveImports(path.parse(xiPath), xiFile);
});
}
return fileNew;
};
const resolveIncludes = (fp, file) => {
const rootEl = fp.ext=='.xsd' ? 'xs:schema' : 'xsl:stylesheet';
const rootRe = RegExp('[\\s\\S]*?<'+rootEl+'[^>]*>([\\s\\S]*?)</'+rootEl+'>');
let fileNew = file.replace(/<!--(?:(?!-->)[\s\S])*?-->/g, ''); // first remove all comments (so disabled includes are not resolved)
const anyArr = file.match(/<xs:any\w*/);
if (anyArr) anyArr.forEach(e => { console.log('Element '.red + e.substr(1) + ' was removed from schema!'.red); });
// replace all include elements by the contents of the referenced file
if (fileNew.match(/<xsl?:include/)) {
fileNew = fileNew.replace(/<xsl?:include\s+\w+="(.*?)"\s*\/>/g, (match, g1) => {
const xiPath = path.resolve(fp.dir, g1);
try {
const xiFile = fs.readFileSync(xiPath).toString() // get file
.replace(rootRe, '$1') // return contents of root element
.replace(/<\/?xs:any[^>]*>/g, '') // remove xs:any(Attribute) elements (causes error in xopus if in root file) (4.1 compatibility)
;
return resolveIncludes(path.parse(xiPath), xiFile);
}
catch (e) {
console.log('Illegal reference to path: '.red + e.path);
return match;
}
});
}
return fileNew;
};
module.exports = () => {
return es.map((file, callback) => {
const fp = path.parse(file.path);
if (fp.ext=='.xml' && fp.name.startsWith('_')) callback(); // do not output included xopus config files
else {
const contents = fp.ext=='.xml' ? resolveImports(fp, String(file.contents)) : resolveIncludes(fp, String(file.contents));
file.contents = Buffer.from(contents.replace(/^\s+$/gm, ''));
callback(null, file);
}
});
};