/* Copyright IBM Corp. 2017 */ import { replace } from 'lodash'; import { join as pathJoin, parse as pathParse, relative as pathRelative, resolve as pathResolve } from 'path'; import { Observable } from 'rxjs'; import { map, mergeMap } from 'rxjs/operators'; import { writeTextFileSafe } from './rx.file'; import { readFile as rxReadFile } from './rx.walk'; const VAR_LAYOUTS = 'LAYOUTS'; const SPREAD_LAYOUTS = '...' + VAR_LAYOUTS; const PROP_DECLARATIONS = 'declarations'; const PROP_ENTRY_COMPONENTS = 'entryComponents'; function _isEmpty(aValue: string): boolean { return !aValue || (aValue.trim().length === 0); } function _addToArray(aValue: string, aPrefix: string, aInfix: string, aSuffix: string): string { // check if (_isEmpty(aInfix)) { return `${aPrefix}${aInfix}${SPREAD_LAYOUTS}${aSuffix}`; } // check if (aInfix.includes(SPREAD_LAYOUTS)) { return aValue; } // append return `${aPrefix}${aInfix}, ${SPREAD_LAYOUTS}${aSuffix}`; } function _replaceModule(aValue: string, aPrefix: string, aInfix: string, aSuffix: string): string { // declarations const declEx = /(declarations:\s+\[)([^\]]*)(\])/g; let infix = aInfix.replace(declEx, _addToArray); // check if there exist entry components if (!declEx.test(infix)) { // insert the declaration const sep = _isEmpty(infix) ? '' : ','; infix = `\ndeclarations: [${SPREAD_LAYOUTS}]${sep}${infix}`; } // entry components const entryEx = /(entryComponents:\s+\[)([^\]]*)(\])/g; infix = infix.replace(entryEx, _addToArray); // check if there exist entry components if (!entryEx.test(infix)) { // insert the declaration const sep = _isEmpty(infix) ? '' : ','; infix = `\nentryComponents: [${SPREAD_LAYOUTS}]${sep}${infix}`; } return `${aPrefix}${infix}${aSuffix}`; } function _addLayoutViaRegexp(aLayoutExports: string, aModuleFile: string): Observable { // get the module directory const moduleDir = pathResolve(aModuleFile, '..'); // load the file return rxReadFile(aModuleFile).pipe( mergeMap(module => { // the modified file let mod = module; // look for the layouts import const layoutImport = /import\s+{\s*LAYOUTS\s*}/g; if (!layoutImport.test(mod)) { // get the relative name const parsed = pathParse(pathRelative(moduleDir, aLayoutExports)); // relative path const relPath = replace(pathJoin(parsed.dir, parsed.name), /\\/g, '/'); // insert the import mod = `import { LAYOUTS } from './${relPath}'; ${mod}`; } // find the module const ngModule = /(@NgModule\s*\(\s*{)((?:.|\n|\r)*)(}\)(?:.|\n|\r)*export\s+class)/g; mod = mod.replace(ngModule, _replaceModule); // save the module return writeTextFileSafe(aModuleFile, mod, true); }), map(() => aModuleFile) ); } export { _addLayoutViaRegexp as addLayoutToModule };