UNPKG

simplr-tslint

Version:

A set of TSLint rules used in SimplrJS projects.

157 lines 27.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = require("path"); const ts = require("typescript"); const Lint = require("tslint"); class Rule extends Lint.Rules.AbstractRule { static resolveModuleFilename(moduleName) { return moduleName + this.moduleFilenameSuffix; } apply(sourceFile) { return this.applyWithWalker(new ImportModuleWalker(sourceFile, this.getOptions())); } } Rule.sep = "/"; Rule.searchModulePath = ["app", "modules"].join(Rule.sep); Rule.searchModulePathSplitter = Rule.searchModulePath + Rule.sep; Rule.entryFailureString = "Module should be imported from an entry file."; Rule.insideRelativeFailureString = "A relative import should be used inside the module."; Rule.insideEntryFailureString = "An entry file import should not be used inside the module."; Rule.forbiddenReexportAllFailureString = "Forbidden 'export * from', use named re-exports."; Rule.moduleFilenameSuffix = "-module"; Rule.reexportPathRegex = /export[\s\S]*from[\s]*[\'\"](.*)[\'\"]/; Rule.reexportAllPathRegex = /export[\s\S]*\*/; exports.Rule = Rule; class ImportModuleWalker extends Lint.RuleWalker { /** * Update import path with module entry file. */ importEntryFileFixer(start, length, prefix, moduleName, fullModuleName, quoteSymbol) { const resolvedImport = [ prefix + Rule.searchModulePath, moduleName, fullModuleName + quoteSymbol ].join(Rule.sep); return new Lint.Replacement(start, length, resolvedImport); } /** * Change path to relative. */ importWithRelativePathFixer(start, length, importFileName, sourceSplitPath, importSplitPath, quoteSymbol) { const sourcePath = sourceSplitPath.slice(0, -1).join(Rule.sep); const importPath = importSplitPath.slice(0, -1).join(Rule.sep); const relativePath = path.relative(sourcePath, importPath).split(path.sep); relativePath.push(importFileName); let relativePathString = relativePath.join(Rule.sep); if (relativePathString[0] === Rule.sep) { relativePathString = "." + relativePathString; } else if (relativePathString[0] !== ".") { relativePathString = `.${Rule.sep}${relativePathString}`; } const fixedPath = `${quoteSymbol}${relativePathString}${quoteSymbol}`; return new Lint.Replacement(start, length, fixedPath); } /** * Generate path details object from pathname. */ parsePathDetails(pathname, withQuotes = true) { const [prefix, suffix] = pathname.split(Rule.searchModulePathSplitter); const [moduleName, ...importSplitPath] = suffix.split(Rule.sep); if (withQuotes) { importSplitPath[importSplitPath.length - 1] = importSplitPath[importSplitPath.length - 1].slice(0, -1); } const [fileName] = importSplitPath.slice(-1); return { prefix: prefix, suffix: suffix, moduleName: moduleName, fullModuleName: Rule.resolveModuleFilename(moduleName), splitPath: importSplitPath, fileName: fileName, withQuotes: withQuotes }; } /** * Validate import line. */ startValidating(sourceFile, importFile, importStart, quote = "") { const sourceFileIsFromModule = sourceFile.indexOf(Rule.searchModulePath) > -1; const importFileIsFromModule = importFile.indexOf(Rule.searchModulePath) > -1; if (!sourceFileIsFromModule && !importFileIsFromModule) { return; } // Check if importing file is not from module if (!importFileIsFromModule) { // Check if source file is from module if (sourceFileIsFromModule) { const sourceDetails = this.parsePathDetails(sourceFile, false); const importFileName = importFile.split(Rule.sep).slice(-1)[0].slice(0, -1); const targetFileName = sourceDetails.fullModuleName; // Check if module itself doesn't import from entry file if (importFileName === targetFileName) { this.addFailureAt(importStart, importFile.length, Rule.insideEntryFailureString); } } return; } const importDetails = this.parsePathDetails(importFile, Boolean(quote)); if (sourceFileIsFromModule && importFileIsFromModule) { const sourceDetails = this.parsePathDetails(sourceFile, false); if (sourceDetails.moduleName === importDetails.moduleName) { const fix = this.importWithRelativePathFixer(importStart, importFile.length, importDetails.fileName, sourceDetails.splitPath, importDetails.splitPath, quote); this.addFailureAt(importStart, importFile.length, Rule.insideRelativeFailureString, fix); return; } } if (importFileIsFromModule && (importDetails.splitPath.length > 1 || importDetails.fullModuleName !== importDetails.fileName)) { const fix = this.importEntryFileFixer(importStart, importFile.length, importDetails.prefix, importDetails.moduleName, importDetails.fullModuleName, quote); this.addFailureAt(importStart, importFile.length, Rule.entryFailureString, fix); return; } } startValidatingReExportAll(fullText, sourceFile, node) { const sourceFileIsFromModule = sourceFile.indexOf(Rule.searchModulePath) > -1; if (sourceFileIsFromModule && Rule.reexportAllPathRegex.test(fullText)) { this.addFailureAtNode(node, Rule.forbiddenReexportAllFailureString); } } /** * Visit on import declaration found. */ visitImportDeclaration(node) { const sourceFile = node.getSourceFile().fileName; const importFile = node.moduleSpecifier.getText(); const importStart = node.moduleSpecifier.getStart(); const quoteSymbol = importFile[0]; this.startValidating(sourceFile, importFile, importStart, quoteSymbol); super.visitImportDeclaration(node); } /** * Visit on any source file. */ visitSourceFile(node) { const fullText = node.getFullText(); const sourceFile = node.fileName; if (node.statements.length > 0) { node.statements .filter(x => x.kind === ts.SyntaxKind.ExportDeclaration && x.getFullText().indexOf("from") > -1) .forEach(statement => { const text = statement.getFullText(); const regexResult = Rule.reexportPathRegex.exec(text); if (regexResult == null) { return; } const importFile = regexResult[1]; if (importFile == null) { return; } this.startValidatingReExportAll(text, sourceFile, statement); const importStart = fullText.indexOf(importFile); this.startValidating(sourceFile, importFile, importStart); }); } super.visitSourceFile(node); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1wb3J0TW9kdWxlUnVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9pbXBvcnRNb2R1bGVSdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkJBQTZCO0FBQzdCLGlDQUFpQztBQUNqQywrQkFBK0I7QUFZL0IsVUFBa0IsU0FBUSxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVk7SUFnQnRDLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxVQUFrQjtRQUNsRCxPQUFPLFVBQVUsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUM7SUFDbEQsQ0FBQztJQUVNLEtBQUssQ0FBQyxVQUF5QjtRQUNsQyxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxrQkFBa0IsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN2RixDQUFDOztBQXJCc0IsUUFBRyxHQUFXLEdBQUcsQ0FBQztBQUVsQixxQkFBZ0IsR0FBVyxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzdELDZCQUF3QixHQUFXLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDO0FBRXBFLHVCQUFrQixHQUFXLCtDQUErQyxDQUFDO0FBQzdFLGdDQUEyQixHQUFXLHFEQUFxRCxDQUFDO0FBQzVGLDZCQUF3QixHQUFXLDREQUE0RCxDQUFDO0FBQ2hHLHNDQUFpQyxHQUFXLGtEQUFrRCxDQUFDO0FBRS9GLHlCQUFvQixHQUFXLFNBQVMsQ0FBQztBQUV6QyxzQkFBaUIsR0FBVyx3Q0FBd0MsQ0FBQztBQUNyRSx5QkFBb0IsR0FBVyxpQkFBaUIsQ0FBQztBQWQ1RSxvQkF1QkM7QUFFRCx3QkFBeUIsU0FBUSxJQUFJLENBQUMsVUFBVTtJQUM1Qzs7T0FFRztJQUNLLG9CQUFvQixDQUN4QixLQUFhLEVBQ2IsTUFBYyxFQUNkLE1BQWMsRUFD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QUNqQixNQUFNLElBQUksR0FBRyxTQUFTLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBRXJDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3RELElBQUksV0FBVyxJQUFJLElBQUksRUFBRTtvQkFDckIsT0FBTztpQkFDVjtnQkFFRCxNQUFNLFVBQVUsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2xDLElBQUksVUFBVSxJQUFJLElBQUksRUFBRTtvQkFDcEIsT0FBTztpQkFDVjtnQkFFRCxJQUFJLENBQUMsMEJBQTBCLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFFN0QsTUFBTSxXQUFXLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDakQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBQzlELENBQUMsQ0FBQyxDQUFDO1NBQ1Y7UUFFRCxLQUFLLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2hDLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIjtcclxuaW1wb3J0ICogYXMgdHMgZnJvbSBcInR5cGVzY3JpcHRcIjtcclxuaW1wb3J0ICogYXMgTGludCBmcm9tIFwidHNsaW50XCI7XHJcblxyXG5pbnRlcmZhY2UgUGF0aERldGFpbHMge1xyXG4gICAgcHJlZml4OiBzdHJpbmc7XHJcbiAgICBzdWZmaXg6IHN0cmluZztcclxuICAgIG1vZHVsZU5hbWU6IHN0cmluZztcclxuICAgIGZ1bGxNb2R1bGVOYW1lOiBzdHJpbmc7XHJcbiAgICBmaWxlTmFtZTogc3RyaW5nO1xyXG4gICAgc3BsaXRQYXRoOiBzdHJpbmdbXTtcclxuICAgIHdpdGhRdW90ZXM6IGJvb2xlYW47XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBSdWxlIGV4dGVuZHMgTGludC5SdWxlcy5BYnN0cmFjdFJ1bGUge1xyXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBzZXA6IHN0cmluZyA9IFwiL1wiO1xyXG5cclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgc2VhcmNoTW9kdWxlUGF0aDogc3RyaW5nID0gW1wiYXBwXCIsIFwibW9kdWxlc1wiXS5qb2luKFJ1bGUuc2VwKTtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgc2VhcmNoTW9kdWxlUGF0aFNwbGl0dGVyOiBzdHJpbmcgPSBSdWxlLnNlYXJjaE1vZHVsZVBhdGggKyBSdWxlLnNlcDtcclxuXHJcbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IGVudHJ5RmFpbHVyZVN0cmluZzogc3RyaW5nID0gXCJNb2R1bGUgc2hvdWxkIGJlIGltcG9ydGVkIGZyb20gYW4gZW50cnkgZmlsZS5cIjtcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgaW5zaWRlUmVsYXRpdmVGYWlsdXJlU3RyaW5nOiBzdHJpbmcgPSBcIkEgcmVsYXRpdmUgaW1wb3J0IHNob3VsZCBiZSB1c2VkIGluc2lkZSB0aGUgbW9kdWxlLlwiO1xyXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBpbnNpZGVFbnRyeUZhaWx1cmVTdHJpbmc6IHN0cmluZyA9IFwiQW4gZW50cnkgZmlsZSBpbXBvcnQgc2hvdWxkIG5vdCBiZSB1c2VkIGluc2lkZSB0aGUgbW9kdWxlLlwiO1xyXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBmb3JiaWRkZW5SZWV4cG9ydEFsbEZhaWx1cmVTdHJpbmc6IHN0cmluZyA9IFwiRm9yYmlkZGVuICdleHBvcnQgKiBmcm9tJywgdXNlIG5hbWVkIHJlLWV4cG9ydHMuXCI7XHJcblxyXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBtb2R1bGVGaWxlbmFtZVN1ZmZpeDogc3RyaW5nID0gXCItbW9kdWxlXCI7XHJcblxyXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSByZWV4cG9ydFBhdGhSZWdleDogUmVnRXhwID0gL2V4cG9ydFtcXHNcXFNdKmZyb21bXFxzXSpbXFwnXFxcIl0oLiopW1xcJ1xcXCJdLztcclxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgcmVleHBvcnRBbGxQYXRoUmVnZXg6IFJlZ0V4cCA9IC9leHBvcnRbXFxzXFxTXSpcXCovO1xyXG5cclxuICAgIHB1YmxpYyBzdGF0aWMgcmVzb2x2ZU1vZHVsZUZpbGVuYW1lKG1vZHVsZU5hbWU6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIG1vZHVsZU5hbWUgKyB0aGlzLm1vZHVsZUZpbGVuYW1lU3VmZml4O1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhcHBseShzb3VyY2VGaWxlOiB0cy5Tb3VyY2VGaWxlKTogTGludC5SdWxlRmFpbHVyZVtdIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5hcHBseVdpdGhXYWxrZXIobmV3IEltcG9ydE1vZHVsZVdhbGtlcihzb3VyY2VGaWxlLCB0aGlzLmdldE9wdGlvbnMoKSkpO1xyXG4gICAgfVxyXG59XHJcblxyXG5jbGFzcyBJbXBvcnRNb2R1bGVXYWxrZXIgZXh0ZW5kcyBMaW50LlJ1bGVXYWxrZXIge1xyXG4gICAgLyoqXHJcbiAgICAgKiBVcGRhdGUgaW1wb3J0IHBhdGggd2l0aCBtb2R1bGUgZW50cnkgZmlsZS5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBpbXBvcnRFbnRyeUZpbGVGaXhlcihcclxuICAgICAgICBzdGFydDogbnVtYmVyLFxyXG4gICAgICAgIGxlbmd0aDogbnVtYmVyLFxyXG4gICAgICAgIHByZWZpeDogc3RyaW5nLFxyXG4gICAgICAgIG1vZHVsZU5hbWU6IHN0cmluZyxcclxuICAgICAgICBmdWxsTW9kdWxlTmFtZTogc3RyaW5nLFxyXG4gICAgICAgIHF1b3RlU3ltYm9sOiBzdHJpbmdcclxuICAgICk6IExpbnQuUmVwbGFjZW1lbnQge1xyXG5cclxuICAgICAgICBjb25zdCByZXNvbHZlZEltcG9ydCA9IFtcclxuICAgICAgICAgICAgcHJlZml4ICsgUnVsZS5zZWFyY2hNb2R1bGVQYXRoLFxyXG4gICAgICAgICAgICBtb2R1bGVOYW1lLFxyXG4gICAgICAgICAgICBmdWxsTW9kdWxlTmFtZSArIHF1b3RlU3ltYm9sXHJcbiAgICAgICAgXS5qb2luKFJ1bGUuc2VwKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBMaW50LlJlcGxhY2VtZW50KHN0YXJ0LCBsZW5ndGgsIHJlc29sdmVkSW1wb3J0KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENoYW5nZSBwYXRoIHRvIHJlbGF0aXZlLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGltcG9ydFdpdGhSZWxhdGl2ZVBhdGhGaXhlcihcclxuICAgICAgICBzdGFydDogbnVtYmVyLFxyXG4gICAgICAgIGxlbmd0aDogbnVtYmVyLFxyXG4gICAgICAgIGltcG9ydEZpbGVOYW1lOiBzdHJpbmcsXHJcbiAgICAgICAgc291cmNlU3BsaXRQYXRoOiBzdHJpbmdbXSxcclxuICAgICAgICBpbXBvcnRTcGxpdFBhdGg6IHN0cmluZ1tdLFxyXG4gICAgICAgIHF1b3RlU3ltYm9sOiBzdHJpbmdcclxuICAgICk6IExpbnQuUmVwbGFjZW1lbnQge1xyXG5cclxuICAgICAgICBjb25zdCBzb3VyY2VQYXRoID0gc291cmNlU3BsaXRQYXRoLnNsaWNlKDAsIC0xKS5qb2luKFJ1bGUuc2VwKTtcclxuICAgICAgICBjb25zdCBpbXBvcnRQYXRoID0gaW1wb3J0U3BsaXRQYXRoLnNsaWNlKDAsIC0xKS5qb2luKFJ1bGUuc2VwKTtcclxuXHJcbiAgICAgICAgY29uc3QgcmVsYXRpdmVQYXRoID0gcGF0aC5yZWxhdGl2ZShzb3VyY2VQYXRoLCBpbXBvcnRQYXRoKS5zcGxpdChwYXRoLnNlcCk7XHJcbiAgICAgICAgcmVsYXRpdmVQYXRoLnB1c2goaW1wb3J0RmlsZU5hbWUpO1xyXG5cclxuICAgICAgICBsZXQgcmVsYXRpdmVQYXRoU3RyaW5nID0gcmVsYXRpdmVQYXRoLmpvaW4oUnVsZS5zZXApO1xyXG5cclxuICAgICAgICBpZiAocmVsYXRpdmVQYXRoU3RyaW5nWzBdID09PSBSdWxlLnNlcCkge1xyXG4gICAgICAgICAgICByZWxhdGl2ZVBhdGhTdHJpbmcgPSBcIi5cIiArIHJlbGF0aXZlUGF0aFN0cmluZztcclxuICAgICAgICB9IGVsc2UgaWYgKHJlbGF0aXZlUGF0aFN0cmluZ1swXSAhPT0gXCIuXCIpIHtcclxuICAgICAgICAgICAgcmVsYXRpdmVQYXRoU3RyaW5nID0gYC4ke1J1bGUuc2VwfSR7cmVsYXRpdmVQYXRoU3RyaW5nfWA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBmaXhlZFBhdGggPSBgJHtxdW90ZVN5bWJvbH0ke3JlbGF0aXZlUGF0aFN0cmluZ30ke3F1b3RlU3ltYm9sfWA7XHJcblxyXG4gICAgICAgIHJldHVybiBuZXcgTGludC5SZXBsYWNlbWVudChzdGFydCwgbGVuZ3RoLCBmaXhlZFBhdGgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2VuZXJhdGUgcGF0aCBkZXRhaWxzIG9iamVjdCBmcm9tIHBhdGhuYW1lLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIHBhcnNlUGF0aERldGFpbHMocGF0aG5hbWU6IHN0cmluZywgd2l0aFF1b3RlczogYm9vbGVhbiA9IHRydWUpOiBQYXRoRGV0YWlscyB7XHJcbiAgICAgICAgY29uc3QgW3ByZWZpeCwgc3VmZml4XSA9IHBhdGhuYW1lLnNwbGl0KFJ1bGUuc2VhcmNoTW9kdWxlUGF0aFNwbGl0dGVyKTtcclxuICAgICAgICBjb25zdCBbbW9kdWxlTmFtZSwgLi4uaW1wb3J0U3BsaXRQYXRoXSA9IHN1ZmZpeC5zcGxpdChSdWxlLnNlcCk7XHJcblxyXG4gICAgICAgIGlmICh3aXRoUXVvdGVzKSB7XHJcbiAgICAgICAgICAgIGltcG9ydFNwbGl0UGF0aFtpbXBvcnRTcGxpdFBhdGgubGVuZ3RoIC0gMV0gPSBpbXBvcnRTcGxpdFBhdGhbaW1wb3J0U3BsaXRQYXRoLmxlbmd0aCAtIDFdLnNsaWNlKDAsIC0xKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IFtmaWxlTmFtZV0gPSBpbXBvcnRTcGxpdFBhdGguc2xpY2UoLTEpO1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBwcmVmaXg6IHByZWZpeCxcclxuICAgICAgICAgICAgc3VmZml4OiBzdWZmaXgsXHJcbiAgICAgICAgICAgIG1vZHVsZU5hbWU6IG1vZHVsZU5hbWUsXHJcbiAgICAgICAgICAgIGZ1bGxNb2R1bGVOYW1lOiBSdWxlLnJlc29sdmVNb2R1bGVGaWxlbmFtZShtb2R1bGVOYW1lKSxcclxuICAgICAgICAgICAgc3BsaXRQYXRoOiBpbXBvcnRTcGxpdFBhdGgsXHJcbiAgICAgICAgICAgIGZpbGVOYW1lOiBmaWxlTmFtZSxcclxuICAgICAgICAgICAgd2l0aFF1b3Rlczogd2l0aFF1b3Rlc1xyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBWYWxpZGF0ZSBpbXBvcnQgbGluZS5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBzdGFydFZhbGlkYXRpbmcoc291cmNlRmlsZTogc3RyaW5nLCBpbXBvcnRGaWxlOiBzdHJpbmcsIGltcG9ydFN0YXJ0OiBudW1iZXIsIHF1b3RlOiBzdHJpbmcgPSBcIlwiKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3Qgc291cmNlRmlsZUlzRnJvbU1vZHVsZSA9IHNvdXJjZUZpbGUuaW5kZXhPZihSdWxlLnNlYXJjaE1vZHVsZVBhdGgpID4gLTE7XHJcbiAgICAgICAgY29uc3QgaW1wb3J0RmlsZUlzRnJvbU1vZHVsZSA9IGltcG9ydEZpbGUuaW5kZXhPZihSdWxlLnNlYXJjaE1vZHVsZVBhdGgpID4gLTE7XHJcblxyXG4gICAgICAgIGlmICghc291cmNlRmlsZUlzRnJvbU1vZHVsZSAmJiAhaW1wb3J0RmlsZUlzRnJvbU1vZHVsZSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBDaGVjayBpZiBpbXBvcnRpbmcgZmlsZSBpcyBub3QgZnJvbSBtb2R1bGVcclxuICAgICAgICBpZiAoIWltcG9ydEZpbGVJc0Zyb21Nb2R1bGUpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHNvdXJjZSBmaWxlIGlzIGZyb20gbW9kdWxlXHJcbiAgICAgICAgICAgIGlmIChzb3VyY2VGaWxlSXNGcm9tTW9kdWxlKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VEZXRhaWxzID0gdGhpcy5wYXJzZVBhdGhEZXRhaWxzKHNvdXJjZUZpbGUsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGltcG9ydEZpbGVOYW1lID0gaW1wb3J0RmlsZS5zcGxpdChSdWxlLnNlcCkuc2xpY2UoLTEpWzBdLnNsaWNlKDAsIC0xKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldEZpbGVOYW1lID0gc291cmNlRGV0YWlscy5mdWxsTW9kdWxlTmFtZTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiBtb2R1bGUgaXRzZWxmIGRvZXNuJ3QgaW1wb3J0IGZyb20gZW50cnkgZmlsZVxyXG4gICAgICAgICAgICAgICAgaWYgKGltcG9ydEZpbGVOYW1lID09PSB0YXJnZXRGaWxlTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkRmFpbHVyZUF0KGltcG9ydFN0YXJ0LCBpbXBvcnRGaWxlLmxlbmd0aCwgUnVsZS5pbnNpZGVFbnRyeUZhaWx1cmVTdHJpbmcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGltcG9ydERldGFpbHMgPSB0aGlzLnBhcnNlUGF0aERldGFpbHMoaW1wb3J0RmlsZSwgQm9vbGVhbihxdW90ZSkpO1xyXG4gICAgICAgIGlmIChzb3VyY2VGaWxlSXNGcm9tTW9kdWxlICYmIGltcG9ydEZpbGVJc0Zyb21Nb2R1bGUpIHtcclxuICAgICAgICAgICAgY29uc3Qgc291cmNlRGV0YWlscyA9IHRoaXMucGFyc2VQYXRoRGV0YWlscyhzb3VyY2VGaWxlLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGlmIChzb3VyY2VEZXRhaWxzLm1vZHVsZU5hbWUgPT09IGltcG9ydERldGFpbHMubW9kdWxlTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZml4ID0gdGhpcy5pbXBvcnRXaXRoUmVsYXRpdmVQYXRoRml4ZXIoXHJcbiAgICAgICAgICAgICAgICAgICAgaW1wb3J0U3RhcnQsXHJcbiAgICAgICAgICAgICAgICAgICAgaW1wb3J0RmlsZS5sZW5ndGgsXHJcbiAgICAgICAgICAgICAgICAgICAgaW1wb3J0RGV0YWlscy5maWxlTmFtZSxcclxuICAgICAgICAgICAgICAgICAgICBzb3VyY2VEZXRhaWxzLnNwbGl0UGF0aCxcclxuICAgICAgICAgICAgICAgICAgICBpbXBvcnREZXRhaWxzLnNwbGl0UGF0aCxcclxuICAgICAgICAgICAgICAgICAgICBxdW90ZVxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuYWRkRmFpbHVyZUF0KGltcG9ydFN0YXJ0LCBpbXBvcnRGaWxlLmxlbmd0aCwgUnVsZS5pbnNpZGVSZWxhdGl2ZUZhaWx1cmVTdHJpbmcsIGZpeCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChpbXBvcnRGaWxlSXNGcm9tTW9kdWxlICYmIChpbXBvcnREZXRhaWxzLnNwbGl0UGF0aC5sZW5ndGggPiAxIHx8IGltcG9ydERldGFpbHMuZnVsbE1vZHVsZU5hbWUgIT09IGltcG9ydERldGFpbHMuZmlsZU5hbWUpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGZpeCA9IHRoaXMuaW1wb3J0RW50cnlGaWxlRml4ZXIoXHJcbiAgICAgICAgICAgICAgICBpbXBvcnRTdGFydCxcclxuICAgICAgICAgICAgICAgIGltcG9ydEZpbGUubGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgaW1wb3J0RGV0YWlscy5wcmVmaXgsXHJcbiAgICAgICAgICAgICAgICBpbXBvcnREZXRhaWxzLm1vZHVsZU5hbWUsXHJcbiAgICAgICAgICAgICAgICBpbXBvcnREZXRhaWxzLmZ1bGxNb2R1bGVOYW1lLFxyXG4gICAgICAgICAgICAgICAgcXVvdGVcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgdGhpcy5hZGRGYWlsdXJlQXQoaW1wb3J0U3RhcnQsIGltcG9ydEZpbGUubGVuZ3RoLCBSdWxlLmVudHJ5RmFpbHVyZVN0cmluZywgZml4KTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXJ0VmFsaWRhdGluZ1JlRXhwb3J0QWxsKGZ1bGxUZXh0OiBzdHJpbmcsIHNvdXJjZUZpbGU6IHN0cmluZywgbm9kZTogdHMuU3RhdGVtZW50KTogdm9pZCB7XHJcbiAgICAgICAgY29uc3Qgc291cmNlRmlsZUlzRnJvbU1vZHVsZSA9IHNvdXJjZUZpbGUuaW5kZXhPZihSdWxlLnNlYXJjaE1vZHVsZVBhdGgpID4gLTE7XHJcbiAgICAgICAgaWYgKHNvdXJjZUZpbGVJc0Zyb21Nb2R1bGUgJiYgUnVsZS5yZWV4cG9ydEFsbFBhdGhSZWdleC50ZXN0KGZ1bGxUZXh0KSkge1xyXG4gICAgICAgICAgICB0aGlzLmFkZEZhaWx1cmVBdE5vZGUobm9kZSwgUnVsZS5mb3JiaWRkZW5SZWV4cG9ydEFsbEZhaWx1cmVTdHJpbmcpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFZpc2l0IG9uIGltcG9ydCBkZWNsYXJhdGlvbiBmb3VuZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHZpc2l0SW1wb3J0RGVjbGFyYXRpb24obm9kZTogdHMuSW1wb3J0RGVjbGFyYXRpb24pOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBzb3VyY2VGaWxlID0gbm9kZS5nZXRTb3VyY2VGaWxlKCkuZmlsZU5hbWU7XHJcbiAgICAgICAgY29uc3QgaW1wb3J0RmlsZSA9IG5vZGUubW9kdWxlU3BlY2lmaWVyLmdldFRleHQoKTtcclxuICAgICAgICBjb25zdCBpbXBvcnRTdGFydCA9IG5vZGUubW9kdWxlU3BlY2lmaWVyLmdldFN0YXJ0KCk7XHJcbiAgICAgICAgY29uc3QgcXVvdGVTeW1ib2wgPSBpbXBvcnRGaWxlWzBdO1xyXG5cclxuICAgICAgICB0aGlzLnN0YXJ0VmFsaWRhdGluZyhzb3VyY2VGaWxlLCBpbXBvcnRGaWxlLCBpbXBvcnRTdGFydCwgcXVvdGVTeW1ib2wpO1xyXG5cclxuICAgICAgICBzdXBlci52aXNpdEltcG9ydERlY2xhcmF0aW9uKG5vZGUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVmlzaXQgb24gYW55IHNvdXJjZSBmaWxlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdmlzaXRTb3VyY2VGaWxlKG5vZGU6IHRzLlNvdXJjZUZpbGUpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBmdWxsVGV4dCA9IG5vZGUuZ2V0RnVsbFRleHQoKTtcclxuICAgICAgICBjb25zdCBzb3VyY2VGaWxlID0gbm9kZS5maWxlTmFtZTtcclxuXHJcbiAgICAgICAgaWYgKG5vZGUuc3RhdGVtZW50cy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIG5vZGUuc3RhdGVtZW50c1xyXG4gICAgICAgICAgICAgICAgLmZpbHRlcih4ID0+IHgua2luZCA9PT0gdHMuU3ludGF4S2luZC5FeHBvcnREZWNsYXJhdGlvbiAmJiB4LmdldEZ1bGxUZXh0KCkuaW5kZXhPZihcImZyb21cIikgPiAtMSlcclxuICAgICAgICAgICAgICAgIC5mb3JFYWNoKHN0YXRlbWVudCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGV4dCA9IHN0YXRlbWVudC5nZXRGdWxsVGV4dCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCByZWdleFJlc3VsdCA9IFJ1bGUucmVleHBvcnRQYXRoUmVnZXguZXhlYyh0ZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocmVnZXhSZXN1bHQgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbXBvcnRGaWxlID0gcmVnZXhSZXN1bHRbMV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGltcG9ydEZpbGUgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0VmFsaWRhdGluZ1JlRXhwb3J0QWxsKHRleHQsIHNvdXJjZUZpbGUsIHN0YXRlbWVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGltcG9ydFN0YXJ0ID0gZnVsbFRleHQuaW5kZXhPZihpbXBvcnRGaWxlKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0VmFsaWRhdGluZyhzb3VyY2VGaWxlLCBpbXBvcnRGaWxlLCBpbXBvcnRTdGFydCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN1cGVyLnZpc2l0U291cmNlRmlsZShub2RlKTtcclxuICAgIH1cclxufVxyXG4iXX0=