@fimbul/valtyr
Version:
Wotan plugin to behave almost like TSLint
144 lines • 5.91 kB
JavaScript
"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