UNPKG

aemfed

Version:

Upload front-end changes into AEM, refresh relevant resources in the page and get instant notifications from the error.log, all for easier and faster development.

241 lines (240 loc) 9.86 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const less_tree_1 = __importDefault(require("less-tree")); const path_1 = __importDefault(require("path")); const recursive_readdir_1 = __importDefault(require("recursive-readdir")); const tree_model_1 = __importDefault(require("tree-model")); class StyleTree { constructor(relativeJcrPath) { this.tree = new tree_model_1.default(); this.jcrRootDir = path_1.default.resolve(relativeJcrPath); } init() { const model = { children: [], filePath: "", id: "", isMissing: false, type: "root" }; const sw = Date.now(); return new Promise((resolve, reject) => { recursive_readdir_1.default(this.jcrRootDir, (err, files) => { console.log("Read file tree: " + (Date.now() - sw) + " ms"); if (err) { reject(err); return; } let swInner = Date.now(); const rootFilesRegex = /((css|js)\.txt|(\.content\.xml))$/i; const contentXmlFilesRelative = []; const jsTxtFilesRelative = []; const cssTxtFilesRelative = []; const otherFilesRelative = []; files.forEach(filePath => { const filePathRelative = path_1.default.relative(this.jcrRootDir, filePath); let match; if ((match = rootFilesRegex.exec(filePathRelative)) !== null) { if (match[3]) { contentXmlFilesRelative.push(filePathRelative); } else if (match[2] === "css") { cssTxtFilesRelative.push(filePathRelative); } else if (match[2] === "js") { jsTxtFilesRelative.push(filePathRelative); } else { otherFilesRelative.push(filePathRelative); } } }); swInner = Date.now(); cssTxtFilesRelative.forEach(cssTxtFileRelative => { const contentFileRelative = path_1.default.join(path_1.default.dirname(cssTxtFileRelative), ".content.xml"); if (contentXmlFilesRelative.indexOf(contentFileRelative) === -1) { return; } const cssTxtModel = this.getCssTxtModel(cssTxtFileRelative); model.children.push(cssTxtModel); }); swInner = Date.now(); this.rootNode = this.tree.parse(model); console.log("Build style tree: " + (Date.now() - sw) + " ms"); resolve(); }); }); } findClientlibs(filePathRelative) { return this.findClientlibsInternal(this.rootNode, filePathRelative); } getCssTxtModel(cssTxtFileRelative) { const basePathRelative = path_1.default.dirname(cssTxtFileRelative); const cssTxtModel = { children: [], filePath: cssTxtFileRelative, id: cssTxtFileRelative, isMissing: false, type: "csstxt" }; try { const contents = fs_1.default.readFileSync(path_1.default.join(this.jcrRootDir, cssTxtFileRelative), "utf8"); const arrayOfLines = contents.match(/[^\r\n]+/g); if (arrayOfLines && arrayOfLines.length > 0) { let prefix = ""; arrayOfLines.forEach((line) => { const baseMatch = /#base=(.*)/.exec(line); if (baseMatch !== null) { prefix = baseMatch[1]; } else { const sourceLine = line.trim(); if (sourceLine.indexOf("//") !== 0) { const sourceFileRelative = path_1.default.isAbsolute(sourceLine) ? path_1.default.relative(path_1.default.sep, sourceLine) : path_1.default.join(basePathRelative, prefix, sourceLine); const sourceModel = this.getSourceModel(sourceFileRelative); cssTxtModel.children.push(sourceModel); } } }); } else { } } catch (err) { cssTxtModel.isMissing = true; } return cssTxtModel; } getSourceModel(sourceFileRelative) { sourceFileRelative = path_1.default.normalize(sourceFileRelative); const sourceModel = { children: [], filePath: sourceFileRelative, id: sourceFileRelative, isMissing: false, type: "source" }; if (path_1.default.extname(sourceFileRelative) === ".less") { sourceModel.type = "less"; const newLessTree = this._getLessTree(sourceFileRelative); const importModels = this.lessTree2Model(newLessTree); sourceModel.children = importModels.children; sourceModel.isMissing = importModels.isMissing; } return sourceModel; } lessTree2Model(newLessTree) { const filePathRelative = path_1.default.relative(this.jcrRootDir, newLessTree.path); const model = { children: [], filePath: filePathRelative, id: filePathRelative, isMissing: !newLessTree.contents, type: "less-import" }; if (newLessTree.children) { newLessTree.children.forEach(child => { const childModel = this.lessTree2Model(child); model.children.push(childModel); }); } return model; } findClientlibsInternal(rootNode, filePathRelative) { let pathIndex; (function (pathIndex) { pathIndex[pathIndex["root"] = 0] = "root"; pathIndex[pathIndex["clientlib"] = 1] = "clientlib"; pathIndex[pathIndex["less"] = 2] = "less"; pathIndex[pathIndex["import"] = 3] = "import"; })(pathIndex || (pathIndex = {})); const sw = Date.now(); this._getLessTree("", true); const clientlibCssPathsRelative = []; const nodes = rootNode.all(node => node.model.filePath === filePathRelative); nodes.forEach(node => { const nodePath = node.getPath(); if (nodePath && nodePath.length > pathIndex.clientlib) { const clientlibNode = nodePath[pathIndex.clientlib]; const clientlibCss = path_1.default.dirname(clientlibNode.model.filePath) + ".css"; if (clientlibCssPathsRelative.indexOf(clientlibCss) === -1) { clientlibCssPathsRelative.push(clientlibCss); } } if (node.hasChildren() || node.model.isMissing) { this.updateClientlibs(rootNode, node); } }); if (nodes.length === 0 && path_1.default.basename(filePathRelative) === "css.txt") { console.log("Missing css.txt, so add", filePathRelative); this.updateClientlibs(rootNode, filePathRelative); } return clientlibCssPathsRelative; } updateClientlibs(rootNode, node) { let newModel; if (typeof node === "string") { if (path_1.default.basename(node) === "css.txt") { console.log("updateClientlibs add new csstxt"); newModel = this.getCssTxtModel(node); } } else { if (["less", "less-import"].indexOf(node.model.type) > -1) { newModel = this.getSourceModel(node.model.filePath); } else if (["csstxt"].indexOf(node.model.type) > -1) { console.log("updateClientlibs csstxt"); newModel = this.getCssTxtModel(node.model.filePath); } } if (newModel) { const newNode = this.tree.parse(newModel); if (typeof node === "string") { rootNode.addChild(newNode); } else { const parentNode = node.parent; const index = node.getIndex(); node.drop(); if (parentNode) { parentNode.addChildAtIndex(newNode, index); } } return newModel; } } copyFileSync(srcFile, destFile) { let BUF_LENGTH; let buff; let bytesRead; let fdr; let fdw; let pos; BUF_LENGTH = 64 * 1024; buff = new Buffer(BUF_LENGTH); fdr = fs_1.default.openSync(srcFile, "r"); fdw = fs_1.default.openSync(destFile, "w"); bytesRead = 1; pos = 0; while (bytesRead > 0) { bytesRead = fs_1.default.readSync(fdr, buff, 0, BUF_LENGTH, pos); fs_1.default.writeSync(fdw, buff, 0, bytesRead); pos += bytesRead; } fs_1.default.closeSync(fdr); return fs_1.default.closeSync(fdw); } _getLessTree(fileRelative, resetCache) { resetCache = !!resetCache; const tree = less_tree_1.default(path_1.default.join(this.jcrRootDir, fileRelative), this.jcrRootDir, resetCache); return tree; } } exports.StyleTree = StyleTree;