UNPKG

@fimbul/valtyr

Version:

Wotan plugin to behave almost like TSLint

144 lines 5.91 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TslintConfigurationProvider = void 0; const tslib_1 = require("tslib"); const inversify_1 = require("inversify"); const wotan_1 = require("@fimbul/wotan"); const TSLint = require("tslint"); const path = require("path"); /** * Number of .. until the containing node_modules. * __dirname -> src * .. -> project root * ../.. -> node_modules (or @scope) * ../../.. -> node_modules if @scoped package */ const OFFSET_TO_NODE_MODULES = 3; let TslintConfigurationProvider = class TslintConfigurationProvider { constructor(resolver, fs, cacheFactory, builtinResolver, directories, options) { this.resolver = resolver; this.fs = fs; this.cacheFactory = cacheFactory; this.builtinResolver = builtinResolver; this.directories = directories; this.options = options; this.tslintConfigDir = undefined; this.baseConfig = undefined; this.cache = cacheFactory.create(); } find(fileName) { fileName = path.dirname(fileName); let result = this.cache.get(fileName); if (result === undefined && !this.cache.has(fileName)) { result = TSLint.Configuration.findConfigurationPath(null, fileName); const { root } = path.parse(fileName); // prevent infinite loop when result is on different drive const configDirname = result === undefined || root !== path.parse(result).root ? root : path.dirname(result); this.cache.set(fileName, result); while (fileName !== configDirname) { this.cache.set(fileName, result); fileName = path.dirname(fileName); } } return result; } resolve(name, basedir) { var _a; const extensions = [...this.resolver.getDefaultExtensions(), '.json']; if (name.startsWith('tslint:')) { try { (_a = this.tslintConfigDir) !== null && _a !== void 0 ? _a : (this.tslintConfigDir = path.join(this.resolver.resolve('tslint', path.dirname(__dirname), extensions), '../configs')); return this.resolver.resolve(path.join(this.tslintConfigDir, name.substr('tslint:'.length)), '', extensions); } catch { throw new Error(`'${name}' is not a valid builtin configuration, try 'tslint:recommended.'`); } } return this.resolver.resolve(name, basedir, extensions, module.paths.slice(OFFSET_TO_NODE_MODULES)); } load(filename) { return this.parse(TSLint.Configuration.loadConfigurationFromPath(filename), filename); } parse(raw, filename) { const rulesDirectories = raw.rulesDirectory.length === 0 ? undefined : raw.rulesDirectory; const overrides = []; if (raw.rules.size !== 0) overrides.push({ files: ['*', '!*.js?(x)'], rules: new Map(Array.from(raw.rules, mapRules)), }); if (raw.jsRules.size !== 0) overrides.push({ files: ['*.js?(x)'], rules: new Map(Array.from(raw.jsRules, mapRules)), }); return { overrides, filename, extends: this.getBaseConfiguration(), exclude: raw.linterOptions && raw.linterOptions.exclude && mapExcludes(raw.linterOptions.exclude, path.dirname(filename)), }; function mapRules([rule, config]) { return [ rule, { rule, rulesDirectories, severity: config.ruleSeverity, options: config.ruleArguments, }, ]; } } getBaseConfiguration() { if (this.baseConfig !== undefined) return this.baseConfig; if (!this.options.valtyr) return this.baseConfig = []; try { const fullPath = path.join(this.directories.getCurrentDirectory(), '.fimbullinter.yaml'); const configProvider = new wotan_1.DefaultConfigurationProvider(this.fs, this.resolver, this.builtinResolver, this.cacheFactory); const config = configProvider.parse(this.options.valtyr, fullPath, { stack: [], load() { throw new Error('Global configuration is not allowed to extend other configs.'); }, }); validateGlobalConfig(config); return this.baseConfig = [config]; } catch (e) { throw new wotan_1.ConfigurationError(`Error parsing global configuration for 'valtyr': ${e.message}`); } } }; TslintConfigurationProvider = tslib_1.__decorate([ inversify_1.injectable(), tslib_1.__metadata("design:paramtypes", [wotan_1.Resolver, wotan_1.CachedFileSystem, wotan_1.CacheFactory, wotan_1.BuiltinResolver, wotan_1.DirectoryService, wotan_1.GlobalOptions]) ], TslintConfigurationProvider); exports.TslintConfigurationProvider = TslintConfigurationProvider; function mapExcludes(excludes, configDir) { const result = []; for (const e of excludes) result.push(path.relative(configDir, e)); return result; } function validateGlobalConfig(config) { checkNonExistence(config, 'exclude'); checkNonExistence(config, 'rules'); checkNonExistence(config, 'rulesDirectories'); checkNonExistence(config, 'aliases'); if (config.overrides !== undefined) for (const override of config.overrides) checkNonExistence(override, 'rules'); } function checkNonExistence(config, key) { if (config[key] !== undefined) throw new Error(`'${key}' is not allowed in global configuration.`); } //# sourceMappingURL=configuration-provider.js.map