Make ts3.1 the default (#46955)

This commit is contained in:
Nathan Shively-Sanders 2020-08-21 09:38:30 -07:00 committed by GitHub
parent 0f2514fb6d
commit a4eb872994
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 12 additions and 1521 deletions

View File

@ -629,8 +629,8 @@ cli = new CLIEngine({ ignorePattern: 'foo' });
cli = new CLIEngine({ ignorePattern: ['foo', 'bar'] });
cli = new CLIEngine({ useEslintrc: false });
cli = new CLIEngine({ parserOptions: {} });
cli = new CLIEngine({ plugins: ['foo'] });
cli = new CLIEngine({ resolvePluginsRelativeTo: 'test' });
cli = new CLIEngine({ plugins: ['foo'] });
cli = new CLIEngine({ rules: { 'test/example-rule': 1 } });
cli = new CLIEngine({ rulePaths: ['foo'] });
cli = new CLIEngine({ reportUnusedDisableDirectives: true });

View File

@ -6,7 +6,8 @@
// Jason Kwok <https://github.com/JasonHK>
// Brad Zacher <https://github.com/bradzacher>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.2
/// <reference path="helpers.d.ts" />
import { JSONSchema4 } from 'json-schema';
import * as ESTree from 'estree';
@ -393,21 +394,19 @@ export namespace Linter {
type Severity = 0 | 1 | 2;
type RuleLevel = Severity | 'off' | 'warn' | 'error';
interface RuleLevelAndOptions extends Array<any> {
0: RuleLevel;
}
type RuleLevelAndOptions<Options extends any[] = any[]> = Prepend<Partial<Options>, RuleLevel>;
type RuleEntry = RuleLevel | RuleLevelAndOptions;
type RuleEntry<Options extends any[] = any[]> = RuleLevel | RuleLevelAndOptions<Options>;
interface RulesRecord {
[rule: string]: RuleEntry;
}
interface HasRules {
rules?: Partial<RulesRecord>;
interface HasRules<Rules extends RulesRecord = RulesRecord> {
rules?: Partial<Rules>;
}
interface BaseConfig extends HasRules {
interface BaseConfig<Rules extends RulesRecord = RulesRecord> extends HasRules<Rules> {
$schema?: string;
env?: { [name: string]: boolean };
extends?: string | string[];
@ -422,13 +421,13 @@ export namespace Linter {
settings?: { [name: string]: any };
}
interface ConfigOverride extends BaseConfig {
interface ConfigOverride<Rules extends RulesRecord = RulesRecord> extends BaseConfig<Rules> {
excludedFiles?: string | string[];
files: string | string[];
}
// https://github.com/eslint/eslint/blob/v6.8.0/conf/config-schema.js
interface Config extends BaseConfig {
interface Config<Rules extends RulesRecord = RulesRecord> extends BaseConfig<Rules> {
ignorePatterns?: string | string[];
root?: boolean;
}
@ -702,7 +701,7 @@ export namespace RuleTester {
interface SuggestionOutput {
messageId?: string;
desc?: string;
data?: Record<string, any>;
data?: Record<string, unknown>;
output: string;
}

View File

@ -1,11 +0,0 @@
{
"private": true,
"types": "index",
"typesVersions": {
">=3.1.0-0": {
"*": [
"ts3.1/*"
]
}
}
}

View File

@ -1,756 +0,0 @@
import { Comment } from 'estree';
import { AST, SourceCode, Rule, Linter, ESLint, CLIEngine, RuleTester, Scope } from 'eslint';
const SOURCE = `var foo = bar;`;
const AST: AST.Program = {
type: 'Program',
sourceType: 'module',
body: [],
comments: [],
tokens: [],
loc: {
start: { line: 0, column: 0 },
end: { line: 0, column: 0 }
},
range: [0, 0],
};
const TOKEN: AST.Token = {
type: 'Identifier',
value: 'foo',
loc: {
start: { line: 0, column: 0 },
end: { line: 0, column: 3 }
},
range: [0, 3]
};
const COMMENT: Comment = {
type: 'Block',
value: 'foo',
loc: {
start: { line: 0, column: 0 },
end: { line: 0, column: 0 }
},
range: [0, 0],
};
//#region SourceCode
let sourceCode = new SourceCode(SOURCE, AST);
SourceCode.splitLines(SOURCE);
sourceCode.getText();
sourceCode.getText(AST);
sourceCode.getText(AST, 0);
sourceCode.getText(AST, 0, 0);
sourceCode.getLines();
sourceCode.getAllComments();
sourceCode.getComments(AST).leading;
sourceCode.getComments(AST).trailing;
sourceCode.getJSDocComment(AST);
sourceCode.getNodeByRangeIndex(0);
sourceCode.getNodeByRangeIndex(0);
sourceCode.isSpaceBetweenTokens(TOKEN, TOKEN);
const loc = sourceCode.getLocFromIndex(0);
loc.line; // $ExpectType number
loc.column; // $ExpectType number
sourceCode.getIndexFromLoc({ line: 0, column: 0 });
sourceCode.getTokenByRangeStart(0);
sourceCode.getTokenByRangeStart(0, { includeComments: true });
sourceCode.getFirstToken(AST);
sourceCode.getFirstToken(AST, 0);
sourceCode.getFirstToken(AST, { skip: 0 });
sourceCode.getFirstToken(AST, t => t.type === 'Identifier');
sourceCode.getFirstToken(AST, { filter: t => t.type === 'Identifier' });
sourceCode.getFirstToken(AST, { skip: 0, filter: t => t.type === 'Identifier' });
sourceCode.getFirstToken(AST, { includeComments: true });
sourceCode.getFirstToken(AST, { includeComments: true, skip: 0 });
sourceCode.getFirstToken(AST, { includeComments: true, skip: 0, filter: t => t.type === 'Identifier' });
sourceCode.getFirstTokens(AST);
sourceCode.getFirstTokens(AST, 0);
sourceCode.getFirstTokens(AST, { count: 0 });
sourceCode.getFirstTokens(AST, t => t.type === 'Identifier');
sourceCode.getFirstTokens(AST, { filter: t => t.type === 'Identifier' });
sourceCode.getFirstTokens(AST, { count: 0, filter: t => t.type === 'Identifier' });
sourceCode.getFirstTokens(AST, { includeComments: true });
sourceCode.getFirstTokens(AST, { includeComments: true, count: 0 });
sourceCode.getFirstTokens(AST, { includeComments: true, count: 0, filter: t => t.type === 'Identifier' });
sourceCode.getLastToken(AST);
sourceCode.getLastToken(AST, 0);
sourceCode.getLastToken(AST, { skip: 0 });
sourceCode.getLastToken(AST, t => t.type === 'Identifier');
sourceCode.getLastToken(AST, { filter: t => t.type === 'Identifier' });
sourceCode.getLastToken(AST, { skip: 0, filter: t => t.type === 'Identifier' });
sourceCode.getLastToken(AST, { includeComments: true });
sourceCode.getLastToken(AST, { includeComments: true, skip: 0 });
sourceCode.getLastToken(AST, { includeComments: true, skip: 0, filter: t => t.type === 'Identifier' });
sourceCode.getLastTokens(AST);
sourceCode.getLastTokens(AST, 0);
sourceCode.getLastTokens(AST, { count: 0 });
sourceCode.getLastTokens(AST, t => t.type === 'Identifier');
sourceCode.getLastTokens(AST, { filter: t => t.type === 'Identifier' });
sourceCode.getLastTokens(AST, { count: 0, filter: t => t.type === 'Identifier' });
sourceCode.getLastTokens(AST, { includeComments: true });
sourceCode.getLastTokens(AST, { includeComments: true, count: 0 });
sourceCode.getLastTokens(AST, { includeComments: true, count: 0, filter: t => t.type === 'Identifier' });
sourceCode.getTokenBefore(AST);
sourceCode.getTokenBefore(AST, 0);
sourceCode.getTokenBefore(AST, { skip: 0 });
sourceCode.getTokenBefore(AST, t => t.type === 'Identifier');
sourceCode.getTokenBefore(AST, { filter: t => t.type === 'Identifier' });
sourceCode.getTokenBefore(AST, { skip: 0, filter: t => t.type === 'Identifier' });
sourceCode.getTokenBefore(AST, { includeComments: true });
sourceCode.getTokenBefore(AST, { includeComments: true, skip: 0 });
sourceCode.getTokenBefore(AST, { includeComments: true, skip: 0, filter: t => t.type === 'Identifier' });
sourceCode.getTokenBefore(TOKEN, 0);
sourceCode.getTokenBefore(COMMENT, 0);
sourceCode.getTokensBefore(AST);
sourceCode.getTokensBefore(AST, 0);
sourceCode.getTokensBefore(AST, { count: 0 });
sourceCode.getTokensBefore(AST, t => t.type === 'Identifier');
sourceCode.getTokensBefore(AST, { filter: t => t.type === 'Identifier' });
sourceCode.getTokensBefore(AST, { count: 0, filter: t => t.type === 'Identifier' });
sourceCode.getTokensBefore(AST, { includeComments: true });
sourceCode.getTokensBefore(AST, { includeComments: true, count: 0 });
sourceCode.getTokensBefore(AST, { includeComments: true, count: 0, filter: t => t.type === 'Identifier' });
sourceCode.getTokensBefore(TOKEN, 0);
sourceCode.getTokensBefore(COMMENT, 0);
sourceCode.getTokenAfter(AST);
sourceCode.getTokenAfter(AST, 0);
sourceCode.getTokenAfter(AST, { skip: 0 });
sourceCode.getTokenAfter(AST, t => t.type === 'Identifier');
sourceCode.getTokenAfter(AST, { filter: t => t.type === 'Identifier' });
sourceCode.getTokenAfter(AST, { skip: 0, filter: t => t.type === 'Identifier' });
sourceCode.getTokenAfter(AST, { includeComments: true });
sourceCode.getTokenAfter(AST, { includeComments: true, skip: 0 });
sourceCode.getTokenAfter(AST, { includeComments: true, skip: 0, filter: t => t.type === 'Identifier' });
sourceCode.getTokenAfter(TOKEN, 0);
sourceCode.getTokenAfter(COMMENT, 0);
sourceCode.getTokensAfter(AST);
sourceCode.getTokensAfter(AST, 0);
sourceCode.getTokensAfter(AST, { count: 0 });
sourceCode.getTokensAfter(AST, t => t.type === 'Identifier');
sourceCode.getTokensAfter(AST, { filter: t => t.type === 'Identifier' });
sourceCode.getTokensAfter(AST, { count: 0, filter: t => t.type === 'Identifier' });
sourceCode.getTokensAfter(AST, { includeComments: true });
sourceCode.getTokensAfter(AST, { includeComments: true, count: 0 });
sourceCode.getTokensAfter(AST, { includeComments: true, count: 0, filter: t => t.type === 'Identifier' });
sourceCode.getTokensAfter(TOKEN, 0);
sourceCode.getTokensAfter(COMMENT, 0);
sourceCode.getFirstTokenBetween(AST, AST);
sourceCode.getFirstTokenBetween(AST, AST, 0);
sourceCode.getFirstTokenBetween(AST, AST, { skip: 0 });
sourceCode.getFirstTokenBetween(AST, AST, t => t.type === 'Identifier');
sourceCode.getFirstTokenBetween(AST, AST, { filter: t => t.type === 'Identifier' });
sourceCode.getFirstTokenBetween(AST, AST, { skip: 0, filter: t => t.type === 'Identifier' });
sourceCode.getFirstTokenBetween(AST, AST, { includeComments: true });
sourceCode.getFirstTokenBetween(AST, AST, { includeComments: true, skip: 0 });
sourceCode.getFirstTokenBetween(AST, AST, { includeComments: true, skip: 0, filter: t => t.type === 'Identifier' });
sourceCode.getFirstTokensBetween(AST, AST);
sourceCode.getFirstTokensBetween(AST, AST, 0);
sourceCode.getFirstTokensBetween(AST, AST, { count: 0 });
sourceCode.getFirstTokensBetween(AST, AST, t => t.type === 'Identifier');
sourceCode.getFirstTokensBetween(AST, AST, { filter: t => t.type === 'Identifier' });
sourceCode.getFirstTokensBetween(AST, AST, { count: 0, filter: t => t.type === 'Identifier' });
sourceCode.getFirstTokensBetween(AST, AST, { includeComments: true });
sourceCode.getFirstTokensBetween(AST, AST, { includeComments: true, count: 0 });
sourceCode.getFirstTokensBetween(AST, AST, { includeComments: true, count: 0, filter: t => t.type === 'Identifier' });
sourceCode.getLastTokenBetween(AST, AST);
sourceCode.getLastTokenBetween(AST, AST, 0);
sourceCode.getLastTokenBetween(AST, AST, { skip: 0 });
sourceCode.getLastTokenBetween(AST, AST, t => t.type === 'Identifier');
sourceCode.getLastTokenBetween(AST, AST, { filter: t => t.type === 'Identifier' });
sourceCode.getLastTokenBetween(AST, AST, { skip: 0, filter: t => t.type === 'Identifier' });
sourceCode.getLastTokenBetween(AST, AST, { includeComments: true });
sourceCode.getLastTokenBetween(AST, AST, { includeComments: true, skip: 0 });
sourceCode.getLastTokenBetween(AST, AST, { includeComments: true, skip: 0, filter: t => t.type === 'Identifier' });
sourceCode.getLastTokensBetween(AST, AST);
sourceCode.getLastTokensBetween(AST, AST, 0);
sourceCode.getLastTokensBetween(AST, AST, { count: 0 });
sourceCode.getLastTokensBetween(AST, AST, t => t.type === 'Identifier');
sourceCode.getLastTokensBetween(AST, AST, { filter: t => t.type === 'Identifier' });
sourceCode.getLastTokensBetween(AST, AST, { count: 0, filter: t => t.type === 'Identifier' });
sourceCode.getLastTokensBetween(AST, AST, { includeComments: true });
sourceCode.getLastTokensBetween(AST, AST, { includeComments: true, count: 0 });
sourceCode.getLastTokensBetween(AST, AST, { includeComments: true, count: 0, filter: t => t.type === 'Identifier' });
sourceCode.getTokensBetween(AST, AST);
sourceCode.getTokensBetween(AST, AST, 0);
sourceCode.getTokens(AST);
sourceCode.getTokens(AST, 0);
sourceCode.getTokens(AST, 0, 0);
sourceCode.getTokens(AST, t => t.type === 'Identifier');
sourceCode.getTokens(AST, { filter: t => t.type === 'Identifier' });
sourceCode.getTokens(AST, { includeComments: true });
sourceCode.getTokens(AST, { includeComments: true, filter: t => t.type === 'Identifier' });
sourceCode.commentsExistBetween(AST, AST);
sourceCode.commentsExistBetween(TOKEN, TOKEN);
sourceCode.getCommentsBefore(AST);
sourceCode.getCommentsBefore(TOKEN);
sourceCode.getCommentsAfter(AST);
sourceCode.getCommentsAfter(TOKEN);
sourceCode.getCommentsInside(AST);
//#endregion
//#region Scope
const scopeManager: Scope.ScopeManager = {
scopes: [],
globalScope: null,
acquire(node, inner) {
return scopeManager.scopes[0];
},
getDeclaredVariables() {
return [];
}
};
const scope = scopeManager.scopes[0];
const variable = scope.variables[0];
variable.name = 'foo';
variable.identifiers[0].type = 'Identifier';
variable.defs[0].name.type = 'Identifier';
variable.defs[0].type;
variable.defs[0].node;
variable.defs[0].parent;
const reference = scope.references[0];
reference.from = scope;
reference.identifier.type = 'Identifier';
reference.resolved = variable;
reference.writeExpr = AST;
reference.init = true;
reference.isRead();
reference.isReadOnly();
reference.isWrite();
reference.isWriteOnly();
reference.isReadWrite();
//#endregion
//#region Rule
let rule: Rule.RuleModule;
rule = { create(context) { return {}; } };
rule = { create(context) { return {}; }, meta: {} };
rule = { create(context) { return {}; }, meta: {
docs: {
description: 'disallow the use of `console`',
category: 'Possible Errors',
recommended: true,
url: 'https://eslint.org/docs/rules/no-console',
}
}};
rule = { create(context) { return {}; }, meta: { fixable: 'whitespace' }};
rule = { create(context) { return {}; }, meta: { fixable: 'code' }};
rule = { create(context) { return {}; }, meta: { schema: [{ enum: ['always', 'never'] }] }};
rule = { create(context) { return {}; }, meta: { deprecated: true }};
rule = {
create(context) {
return {};
},
meta: { type: 'layout' },
};
rule = {
create(context) {
context.getAncestors();
context.getDeclaredVariables(AST);
context.getFilename();
context.getSourceCode();
context.getScope();
context.markVariableAsUsed('foo');
context.report({ message: 'foo', node: AST });
context.report({ message: 'foo', loc: { line: 0, column: 0 } });
context.report({ message: 'foo', node: AST, data: { foo: 'bar' } });
context.report({ message: 'foo', node: AST, fix: () => null });
context.report({ message: 'foo', node: AST, fix: ruleFixer => ruleFixer.replaceText(AST, 'foo') });
context.report({
message: 'foo',
node: AST,
fix: ruleFixer => {
ruleFixer.insertTextAfter(AST, 'foo');
ruleFixer.insertTextAfter(TOKEN, 'foo');
ruleFixer.insertTextAfterRange([0, 0], 'foo');
ruleFixer.insertTextBefore(AST, 'foo');
ruleFixer.insertTextBefore(TOKEN, 'foo');
ruleFixer.insertTextBeforeRange([0, 0], 'foo');
ruleFixer.remove(AST);
ruleFixer.remove(TOKEN);
ruleFixer.removeRange([0, 0]);
ruleFixer.replaceText(AST, 'foo');
ruleFixer.replaceText(TOKEN, 'foo');
ruleFixer.replaceTextRange([0, 0], 'foo');
return null;
}
});
context.report({
message: 'foo',
node: AST,
fix: ruleFixer => {
return [
ruleFixer.insertTextAfter(AST, 'foo'),
ruleFixer.insertTextAfter(TOKEN, 'foo')
];
}
});
context.report({
message: 'foo',
node: AST,
suggest: [
{
desc: 'foo',
fix: ruleFixer => {
return [
ruleFixer.insertTextAfter(AST, 'foo'),
ruleFixer.insertTextAfter(TOKEN, 'foo')
];
},
},
{
messageId: 'foo',
fix: ruleFixer => {
return [
ruleFixer.insertTextAfter(AST, 'foo'),
ruleFixer.insertTextAfter(TOKEN, 'foo')
];
},
},
],
});
return {
onCodePathStart(codePath, node) {},
onCodePathEnd(codePath, node) {},
onCodePathSegmentStart(segment, node) {},
onCodePathSegmentEnd(segment, node) {},
onCodePathSegmentLoop(fromSegment, toSegment, node) {},
IfStatement(node) {},
'Program:exit'() {},
};
},
};
//#endregion
//#region Linter
const linter = new Linter();
linter.version;
linter.verify(SOURCE, {});
linter.verify(new SourceCode(SOURCE, AST), {});
linter.verify(SOURCE, {}, 'test.js');
linter.verify(SOURCE, {}, {});
linter.verify(SOURCE, {}, { filename: 'test.js' });
linter.verify(SOURCE, {}, { allowInlineConfig: false });
linter.verify(SOURCE, {}, { reportUnusedDisableDirectives: true });
linter.verify(SOURCE, {}, { preprocess: input => input.split(' ') });
linter.verify(SOURCE, {}, { postprocess: problemList => problemList[0] });
linter.verify(SOURCE, { parserOptions: { ecmaVersion: 6 } }, 'test.js');
linter.verify(SOURCE, { parserOptions: { ecmaVersion: 6, ecmaFeatures: { globalReturn: true } } }, 'test.js');
linter.verify(SOURCE, { parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } } }, 'test.js');
linter.verify(SOURCE, { env: { node: true } }, 'test.js');
linter.verify(SOURCE, { globals: { foo: true } }, 'test.js');
linter.verify(SOURCE, { parser: 'custom-parser' }, 'test.js');
linter.verify(SOURCE, { settings: { info: 'foo' } }, 'test.js');
linter.verify(SOURCE, { processor: 'a-plugin/a-processor' }, 'test.js');
linter.verify(SOURCE, { plugins: ['a-plugin'] }, 'test.js');
linter.verify(SOURCE, { root: true }, 'test.js');
linter.verify(SOURCE, { extends: 'eslint-config-bad-guy' }, 'test.js');
linter.verify(SOURCE, { extends: ['eslint-config-bad-guy', 'eslint-config-roblox'] }, 'test.js');
linter.verify(SOURCE, { rules: {} }, 'test.js');
linter.verify(SOURCE, { rules: { quotes: 2 } }, 'test.js');
linter.verify(SOURCE, { rules: { quotes: [2, 'double'] } }, 'test.js');
linter.verify(SOURCE, { rules: { 'no-unused-vars': [2, { vars: 'all' }] } }, 'test.js');
linter.verify(SOURCE, { rules: { 'no-console': 1 } }, 'test.js');
linter.verify(SOURCE, { rules: { 'no-console': 0 } }, 'test.js');
linter.verify(SOURCE, { rules: { 'no-console': 'error' } }, 'test.js');
linter.verify(
SOURCE,
{
rules: { 'no-console': 'error' },
overrides: [
{
extends: ['eslint-config-bad-guy'],
excludedFiles: ['*-test.js', '*.spec.js'],
files: ['*-test.js', '*.spec.js'],
rules: {
'no-unused-expressions': 'off',
},
},
],
},
'test.js',
);
linter.verify(SOURCE, { rules: { 'no-console': 'warn' } }, 'test.js');
linter.verify(SOURCE, { rules: { 'no-console': 'off' } }, 'test.js');
const lintingResult = linter.verify(SOURCE, {});
for (const msg of lintingResult) {
msg.severity = 1;
msg.severity = 2;
msg.ruleId = 'foo';
msg.fatal = true;
msg.message = 'foo';
msg.messageId = 'foo';
msg.line = 0;
msg.endLine = 0;
msg.column = 0;
msg.endColumn = 0;
msg.source = SOURCE;
if (msg.fix) {
msg.fix.text = 'foo';
msg.fix.range = [0, 0];
}
if (msg.suggestions) {
for (const suggestion of msg.suggestions) {
suggestion.desc = 'foo';
suggestion.messageId = 'foo';
suggestion.fix.text = 'foo';
suggestion.fix.range = [0, 0];
}
}
}
linter.verifyAndFix(SOURCE, {});
linter.verifyAndFix(SOURCE, {}, 'test.js');
linter.verifyAndFix(SOURCE, {}, { fix: false });
const fixResult = linter.verifyAndFix(SOURCE, {});
fixResult.fixed = true;
fixResult.output = 'foo';
for (const msg of fixResult.messages) {
msg.ruleId = 'foo';
}
sourceCode = linter.getSourceCode();
linter.defineRule('test', rule);
linter.defineRules({
foo: rule,
bar: rule,
});
linter.getRules();
linter.defineParser('custom-parser', { parse: (src, opts) => AST });
linter.defineParser('custom-parser', {
parseForESLint(src, opts) {
return {
ast: AST,
visitorKeys: {},
parserServices: {},
scopeManager,
};
},
});
//#endregion
//#region ESLint
let eslint: ESLint;
eslint = new ESLint({ allowInlineConfig: false });
eslint = new ESLint({ baseConfig: {} });
eslint = new ESLint({ overrideConfig: {} });
eslint = new ESLint({ overrideConfigFile: 'foo' });
eslint = new ESLint({ cache: true });
eslint = new ESLint({ cacheLocation: 'foo' });
eslint = new ESLint({ cwd: 'foo' });
eslint = new ESLint({ errorOnUnmatchedPattern: true });
eslint = new ESLint({ extensions: ['js'] });
eslint = new ESLint({ fix: true });
eslint = new ESLint({ fix: message => false });
eslint = new ESLint({ fixTypes: ['problem'] });
eslint = new ESLint({ globInputPaths: true });
eslint = new ESLint({ ignore: true });
eslint = new ESLint({ ignorePath: 'foo' });
eslint = new ESLint({ useEslintrc: false });
eslint = new ESLint({ plugins: { foo: {} } });
eslint = new ESLint({ reportUnusedDisableDirectives: 'error' });
eslint = new ESLint({ resolvePluginsRelativeTo: 'test' });
eslint = new ESLint({ rulePaths: ['foo'] });
let resultsPromise = eslint.lintFiles(['myfile.js', 'lib/']);
resultsPromise = eslint.lintText(SOURCE, { filePath: 'foo' });
eslint.calculateConfigForFile('./config.json');
eslint.isPathIgnored('./dist/index.js');
let formatterPromise: Promise<ESLint.Formatter>;
formatterPromise = eslint.loadFormatter('codeframe');
formatterPromise = eslint.loadFormatter();
let data: ESLint.LintResultData;
const meta: Rule.RuleMetaData = {
type: 'suggestion',
docs: {
description: 'disallow unnecessary semicolons',
category: 'Possible Errors',
recommended: true,
url: 'https://eslint.org/docs/rules/no-extra-semi'
},
fixable: 'code',
schema: [],
messages: {
unexpected: 'Unnecessary semicolon.'
}
};
data = { rulesMeta: { 'no-extra-semi': meta } };
const version: string = ESLint.version;
resultsPromise.then(results => {
formatterPromise.then(formatter => formatter.format(results));
formatterPromise.then(formatter => formatter.format(results, data));
ESLint.getErrorResults(results);
ESLint.outputFixes(results);
results[0].errorCount = 0;
results[0].warningCount = 0;
results[0].fixableErrorCount = 0;
results[0].fixableWarningCount = 0;
for (const file of results) {
file.filePath = 'foo.js';
file.errorCount = 0;
file.warningCount = 0;
file.fixableErrorCount = 0;
file.fixableWarningCount = 0;
file.source = 'foo';
file.output = 'foo';
for (const message of file.messages) {
message.ruleId = 'foo';
}
}
});
//#endregion
//#region CLIEngine
let cli: CLIEngine;
cli = new CLIEngine({ allowInlineConfig: false });
cli = new CLIEngine({ baseConfig: false });
cli = new CLIEngine({ baseConfig: { extends: ['lynt'] }});
cli = new CLIEngine({ cache: true });
cli = new CLIEngine({ cacheFile: 'foo' });
cli = new CLIEngine({ configFile: 'foo' });
cli = new CLIEngine({ cwd: 'foo' });
cli = new CLIEngine({ envs: ['browser'] });
cli = new CLIEngine({ extensions: ['js'] });
cli = new CLIEngine({ fix: true });
cli = new CLIEngine({ globals: ['foo'] });
cli = new CLIEngine({ ignore: true });
cli = new CLIEngine({ ignorePath: 'foo' });
cli = new CLIEngine({ ignorePattern: 'foo' });
cli = new CLIEngine({ ignorePattern: ['foo', 'bar'] });
cli = new CLIEngine({ useEslintrc: false });
cli = new CLIEngine({ parserOptions: {} });
cli = new CLIEngine({ resolvePluginsRelativeTo: 'test' });
cli = new CLIEngine({ plugins: ['foo'] });
cli = new CLIEngine({ rules: { 'test/example-rule': 1 } });
cli = new CLIEngine({ rulePaths: ['foo'] });
cli = new CLIEngine({ reportUnusedDisableDirectives: true });
cli = new CLIEngine({ errorOnUnmatchedPattern: false });
let cliReport = cli.executeOnFiles(['myfile.js', 'lib/']);
cliReport = cli.executeOnText(SOURCE, 'foo');
cli.resolveFileGlobPatterns(['**/*']);
cli.getConfigForFile('./config.json');
cli.addPlugin('my-fancy-plugin', {});
cli.isPathIgnored('./dist/index.js');
let cliFormatter: CLIEngine.Formatter;
cliFormatter = cli.getFormatter('codeframe');
cliFormatter = cli.getFormatter();
let cliData: CLIEngine.LintResultData;
const cliMeta: Rule.RuleMetaData = {
type: 'suggestion',
docs: {
description: 'disallow unnecessary semicolons',
category: 'Possible Errors',
recommended: true,
url: 'https://eslint.org/docs/rules/no-extra-semi'
},
fixable: 'code',
schema: [],
messages: {
unexpected: 'Unnecessary semicolon.'
}
};
cliData = { rulesMeta: { 'no-extra-semi': cliMeta } };
cliFormatter(cliReport.results);
cliFormatter(cliReport.results, cliData);
const cliVersion: string = CLIEngine.version;
CLIEngine.getErrorResults(cliReport.results);
cliFormatter = CLIEngine.getFormatter();
cliFormatter = CLIEngine.getFormatter('codeframe');
CLIEngine.outputFixes(cliReport);
cliReport.errorCount = 0;
cliReport.warningCount = 0;
cliReport.fixableErrorCount = 0;
cliReport.fixableWarningCount = 0;
for (const file of cliReport.results) {
file.filePath = 'foo.js';
file.errorCount = 0;
file.warningCount = 0;
file.fixableErrorCount = 0;
file.fixableWarningCount = 0;
file.source = 'foo';
file.output = 'foo';
for (const message of file.messages) {
message.ruleId = 'foo';
}
}
//#endregion
//#region RuleTester
const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2015 } });
ruleTester.run('my-rule', rule, {
valid: [
{ code: 'foo' },
{ code: 'foo', options: [{ allowFoo: true }] },
{ code: 'foo', filename: 'test.js' },
{ code: 'foo', parserOptions: {} },
{ code: 'foo', settings: { foo: true } },
{ code: 'foo', parser: 'foo' },
{ code: 'foo', globals: { foo: true } },
],
invalid: [
{ code: 'foo', errors: 1 },
{ code: 'foo', errors: 1, output: 'foo' },
{ code: 'foo', errors: ['foo'] },
{ code: 'foo', errors: [{ message: 'foo' }] },
{ code: 'foo', errors: [{ message: 'foo', type: 'foo' }] },
{ code: 'foo', errors: [{ message: 'foo', data: { foo: true } }] },
{ code: 'foo', errors: [{ message: 'foo', line: 0 }] },
{ code: 'foo', errors: [{
message: 'foo',
suggestions: [
{
desc: 'foo',
output: 'foo',
},
{
messageId: 'foo',
output: 'foo',
},
],
}] },
]
});
ruleTester.run('simple-valid-test', rule, {
valid: [
'foo',
'bar',
{ code: 'foo', options: [{ allowFoo: true }] },
]
});
//#endregion

View File

@ -1,717 +0,0 @@
/// <reference path="helpers.d.ts" />
import { JSONSchema4 } from 'json-schema';
import * as ESTree from 'estree';
export namespace AST {
type TokenType =
| 'Boolean'
| 'Null'
| 'Identifier'
| 'Keyword'
| 'Punctuator'
| 'JSXIdentifier'
| 'JSXText'
| 'Numeric'
| 'String'
| 'RegularExpression';
interface Token {
type: TokenType;
value: string;
range: Range;
loc: SourceLocation;
}
interface SourceLocation {
start: ESTree.Position;
end: ESTree.Position;
}
type Range = [number, number];
interface Program extends ESTree.Program {
comments: ESTree.Comment[];
tokens: Token[];
loc: SourceLocation;
range: Range;
}
}
export namespace Scope {
interface ScopeManager {
scopes: Scope[];
globalScope: Scope | null;
acquire(node: ESTree.Node, inner?: boolean): Scope | null;
getDeclaredVariables(node: ESTree.Node): Variable[];
}
interface Scope {
type: 'block' | 'catch' | 'class' | 'for' | 'function' | 'function-expression-name' | 'global' | 'module' | 'switch' | 'with' | 'TDZ';
isStrict: boolean;
upper: Scope | null;
childScopes: Scope[];
variableScope: Scope;
block: ESTree.Node;
variables: Variable[];
set: Map<string, Variable>;
references: Reference[];
through: Reference[];
functionExpressionScope: boolean;
}
interface Variable {
name: string;
identifiers: ESTree.Identifier[];
references: Reference[];
defs: Definition[];
}
interface Reference {
identifier: ESTree.Identifier;
from: Scope;
resolved: Variable | null;
writeExpr: ESTree.Node | null;
init: boolean;
isWrite(): boolean;
isRead(): boolean;
isWriteOnly(): boolean;
isReadOnly(): boolean;
isReadWrite(): boolean;
}
type DefinitionType =
| { type: 'CatchClause', node: ESTree.CatchClause, parent: null }
| { type: 'ClassName', node: ESTree.ClassDeclaration | ESTree.ClassExpression, parent: null }
| { type: 'FunctionName', node: ESTree.FunctionDeclaration | ESTree.FunctionExpression, parent: null }
| { type: 'ImplicitGlobalVariable', node: ESTree.Program, parent: null }
| { type: 'ImportBinding', node: ESTree.ImportSpecifier | ESTree.ImportDefaultSpecifier | ESTree.ImportNamespaceSpecifier, parent: ESTree.ImportDeclaration }
| { type: 'Parameter', node: ESTree.FunctionDeclaration | ESTree.FunctionExpression | ESTree.ArrowFunctionExpression, parent: null }
| { type: 'TDZ', node: any, parent: null }
| { type: 'Variable', node: ESTree.VariableDeclarator, parent: ESTree.VariableDeclaration };
type Definition = DefinitionType & { name: ESTree.Identifier };
}
//#region SourceCode
export class SourceCode {
text: string;
ast: AST.Program;
lines: string[];
hasBOM: boolean;
parserServices: SourceCode.ParserServices;
scopeManager: Scope.ScopeManager;
visitorKeys: SourceCode.VisitorKeys;
constructor(text: string, ast: AST.Program);
constructor(config: SourceCode.Config);
static splitLines(text: string): string[];
getText(node?: ESTree.Node, beforeCount?: number, afterCount?: number): string;
getLines(): string[];
getAllComments(): ESTree.Comment[];
getComments(node: ESTree.Node): { leading: ESTree.Comment[], trailing: ESTree.Comment[] };
getJSDocComment(node: ESTree.Node): AST.Token | null;
getNodeByRangeIndex(index: number): ESTree.Node | null;
isSpaceBetweenTokens(first: AST.Token, second: AST.Token): boolean;
getLocFromIndex(index: number): ESTree.Position;
getIndexFromLoc(location: ESTree.Position): number;
// Inherited methods from TokenStore
// ---------------------------------
getTokenByRangeStart(offset: number, options?: { includeComments?: boolean }): AST.Token | null;
getFirstToken(node: ESTree.Node, options?: SourceCode.CursorWithSkipOptions): AST.Token | null;
getFirstTokens(node: ESTree.Node, options?: SourceCode.CursorWithCountOptions): AST.Token[];
getLastToken(node: ESTree.Node, options?: SourceCode.CursorWithSkipOptions): AST.Token | null;
getLastTokens(node: ESTree.Node, options?: SourceCode.CursorWithCountOptions): AST.Token[];
getTokenBefore(node: ESTree.Node | AST.Token | ESTree.Comment, options?: SourceCode.CursorWithSkipOptions): AST.Token | null;
getTokensBefore(node: ESTree.Node | AST.Token | ESTree.Comment, options?: SourceCode.CursorWithCountOptions): AST.Token[];
getTokenAfter(node: ESTree.Node | AST.Token | ESTree.Comment, options?: SourceCode.CursorWithSkipOptions): AST.Token | null;
getTokensAfter(node: ESTree.Node | AST.Token | ESTree.Comment, options?: SourceCode.CursorWithCountOptions): AST.Token[];
getFirstTokenBetween(
left: ESTree.Node | AST.Token | ESTree.Comment,
right: ESTree.Node | AST.Token | ESTree.Comment,
options?: SourceCode.CursorWithSkipOptions
): AST.Token | null;
getFirstTokensBetween(
left: ESTree.Node | AST.Token | ESTree.Comment,
right: ESTree.Node | AST.Token | ESTree.Comment,
options?: SourceCode.CursorWithCountOptions
): AST.Token[];
getLastTokenBetween(
left: ESTree.Node | AST.Token | ESTree.Comment,
right: ESTree.Node | AST.Token | ESTree.Comment,
options?: SourceCode.CursorWithSkipOptions
): AST.Token | null;
getLastTokensBetween(
left: ESTree.Node | AST.Token | ESTree.Comment,
right: ESTree.Node | AST.Token | ESTree.Comment,
options?: SourceCode.CursorWithCountOptions
): AST.Token[];
getTokensBetween(
left: ESTree.Node | AST.Token | ESTree.Comment,
right: ESTree.Node | AST.Token | ESTree.Comment,
padding?: number | SourceCode.FilterPredicate | SourceCode.CursorWithCountOptions
): AST.Token[];
getTokens(node: ESTree.Node, beforeCount?: number, afterCount?: number): AST.Token[];
getTokens(node: ESTree.Node, options: SourceCode.FilterPredicate | SourceCode.CursorWithCountOptions): AST.Token[];
commentsExistBetween(left: ESTree.Node | AST.Token, right: ESTree.Node | AST.Token): boolean;
getCommentsBefore(nodeOrToken: ESTree.Node | AST.Token): ESTree.Comment[];
getCommentsAfter(nodeOrToken: ESTree.Node | AST.Token): ESTree.Comment[];
getCommentsInside(node: ESTree.Node): ESTree.Comment[];
}
export namespace SourceCode {
interface Config {
text: string;
ast: AST.Program;
parserServices?: ParserServices;
scopeManager?: Scope.ScopeManager;
visitorKeys?: VisitorKeys;
}
type ParserServices = any;
interface VisitorKeys {
[nodeType: string]: string[];
}
type FilterPredicate = (tokenOrComment: AST.Token | ESTree.Comment) => boolean;
type CursorWithSkipOptions = number | FilterPredicate | {
includeComments?: boolean;
filter?: FilterPredicate;
skip?: number;
};
type CursorWithCountOptions = number | FilterPredicate | {
includeComments?: boolean;
filter?: FilterPredicate;
count?: number;
};
}
//#endregion
export namespace Rule {
interface RuleModule {
create(context: RuleContext): RuleListener;
meta?: RuleMetaData;
}
type NodeTypes = ESTree.Node['type'];
type NodeListener = { [T in NodeTypes]?: (node: ESTree.Node) => void };
interface RuleListener extends NodeListener {
onCodePathStart?(codePath: CodePath, node: ESTree.Node): void;
onCodePathEnd?(codePath: CodePath, node: ESTree.Node): void;
onCodePathSegmentStart?(segment: CodePathSegment, node: ESTree.Node): void;
onCodePathSegmentEnd?(segment: CodePathSegment, node: ESTree.Node): void;
onCodePathSegmentLoop?(fromSegment: CodePathSegment, toSegment: CodePathSegment, node: ESTree.Node): void;
[key: string]:
| ((codePath: CodePath, node: ESTree.Node) => void)
| ((segment: CodePathSegment, node: ESTree.Node) => void)
| ((fromSegment: CodePathSegment, toSegment: CodePathSegment, node: ESTree.Node) => void)
| ((node: ESTree.Node) => void)
| undefined;
}
interface CodePath {
id: string;
initialSegment: CodePathSegment;
finalSegments: CodePathSegment[];
returnedSegments: CodePathSegment[];
thrownSegments: CodePathSegment[];
currentSegments: CodePathSegment[];
upper: CodePath | null;
childCodePaths: CodePath[];
}
interface CodePathSegment {
id: string;
nextSegments: CodePathSegment[];
prevSegments: CodePathSegment[];
reachable: boolean;
}
interface RuleMetaData {
docs?: {
description?: string;
category?: string;
recommended?: boolean;
url?: string;
};
messages?: { [messageId: string]: string };
fixable?: 'code' | 'whitespace';
schema?: JSONSchema4 | JSONSchema4[];
deprecated?: boolean;
type?: 'problem' | 'suggestion' | 'layout';
}
interface RuleContext {
id: string;
options: any[];
settings: { [name: string]: any };
parserPath: string;
parserOptions: Linter.ParserOptions;
parserServices: SourceCode.ParserServices;
getAncestors(): ESTree.Node[];
getDeclaredVariables(node: ESTree.Node): Scope.Variable[];
getFilename(): string;
getScope(): Scope.Scope;
getSourceCode(): SourceCode;
markVariableAsUsed(name: string): boolean;
report(descriptor: ReportDescriptor): void;
}
interface ReportDescriptorOptionsBase {
data?: { [key: string]: string };
fix?: null | ((fixer: RuleFixer) => null | Fix | IterableIterator<Fix> | Fix[]);
}
type SuggestionDescriptorMessage = { desc: string } | { messageId: string };
type SuggestionReportDescriptor = SuggestionDescriptorMessage & ReportDescriptorOptionsBase;
interface ReportDescriptorOptions extends ReportDescriptorOptionsBase {
suggest?: SuggestionReportDescriptor[] | null;
}
type ReportDescriptor = ReportDescriptorMessage & ReportDescriptorLocation & ReportDescriptorOptions;
type ReportDescriptorMessage = { message: string } | { messageId: string };
type ReportDescriptorLocation =
| { node: ESTree.Node }
| { loc: AST.SourceLocation | { line: number; column: number } };
interface RuleFixer {
insertTextAfter(nodeOrToken: ESTree.Node | AST.Token, text: string): Fix;
insertTextAfterRange(range: AST.Range, text: string): Fix;
insertTextBefore(nodeOrToken: ESTree.Node | AST.Token, text: string): Fix;
insertTextBeforeRange(range: AST.Range, text: string): Fix;
remove(nodeOrToken: ESTree.Node | AST.Token): Fix;
removeRange(range: AST.Range): Fix;
replaceText(nodeOrToken: ESTree.Node | AST.Token, text: string): Fix;
replaceTextRange(range: AST.Range, text: string): Fix;
}
interface Fix {
range: AST.Range;
text: string;
}
}
//#region Linter
export class Linter {
static version: string;
version: string;
constructor(options?: { cwd?: string });
verify(code: SourceCode | string, config: Linter.Config, filename?: string): Linter.LintMessage[];
verify(code: SourceCode | string, config: Linter.Config, options: Linter.LintOptions): Linter.LintMessage[];
verifyAndFix(code: string, config: Linter.Config, filename?: string): Linter.FixReport;
verifyAndFix(code: string, config: Linter.Config, options: Linter.FixOptions): Linter.FixReport;
getSourceCode(): SourceCode;
defineRule(name: string, rule: Rule.RuleModule): void;
defineRules(rules: { [name: string]: Rule.RuleModule }): void;
getRules(): Map<string, Rule.RuleModule>;
defineParser(name: string, parser: Linter.ParserModule): void;
}
export namespace Linter {
type Severity = 0 | 1 | 2;
type RuleLevel = Severity | 'off' | 'warn' | 'error';
type RuleLevelAndOptions<Options extends any[] = any[]> = Prepend<Partial<Options>, RuleLevel>;
type RuleEntry<Options extends any[] = any[]> = RuleLevel | RuleLevelAndOptions<Options>;
interface RulesRecord {
[rule: string]: RuleEntry;
}
interface HasRules<Rules extends RulesRecord = RulesRecord> {
rules?: Partial<Rules>;
}
interface BaseConfig<Rules extends RulesRecord = RulesRecord> extends HasRules<Rules> {
$schema?: string;
env?: { [name: string]: boolean };
extends?: string | string[];
globals?: { [name: string]: boolean };
noInlineConfig?: boolean;
overrides?: ConfigOverride[];
parser?: string;
parserOptions?: ParserOptions;
plugins?: string[];
processor?: string;
reportUnusedDisableDirectives?: boolean;
settings?: { [name: string]: any };
}
interface ConfigOverride<Rules extends RulesRecord = RulesRecord> extends BaseConfig<Rules> {
excludedFiles?: string | string[];
files: string | string[];
}
// https://github.com/eslint/eslint/blob/v6.8.0/conf/config-schema.js
interface Config<Rules extends RulesRecord = RulesRecord> extends BaseConfig<Rules> {
ignorePatterns?: string | string[];
root?: boolean;
}
interface ParserOptions {
ecmaVersion?: 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020;
sourceType?: 'script' | 'module';
ecmaFeatures?: {
globalReturn?: boolean;
impliedStrict?: boolean;
jsx?: boolean;
experimentalObjectRestSpread?: boolean;
[key: string]: any;
};
[key: string]: any;
}
interface LintOptions {
filename?: string;
preprocess?: (code: string) => string[];
postprocess?: (problemLists: LintMessage[][]) => LintMessage[];
filterCodeBlock?: boolean;
disableFixes?: boolean;
allowInlineConfig?: boolean;
reportUnusedDisableDirectives?: boolean;
}
interface LintSuggestion {
desc: string;
fix: Rule.Fix;
messageId?: string;
}
interface LintMessage {
column: number;
line: number;
endColumn?: number;
endLine?: number;
ruleId: string | null;
message: string;
messageId?: string;
nodeType?: string;
fatal?: true;
severity: Severity;
fix?: Rule.Fix;
/** @deprecated Use `linter.getSourceCode()` */
source?: string | null;
suggestions?: LintSuggestion[];
}
interface FixOptions extends LintOptions {
fix?: boolean;
}
interface FixReport {
fixed: boolean;
output: string;
messages: LintMessage[];
}
type ParserModule =
| {
parse(text: string, options?: any): AST.Program;
}
| {
parseForESLint(text: string, options?: any): ESLintParseResult;
};
interface ESLintParseResult {
ast: AST.Program;
parserServices?: SourceCode.ParserServices;
scopeManager?: Scope.ScopeManager;
visitorKeys?: SourceCode.VisitorKeys;
}
}
//#endregion
//#region ESLint
export class ESLint {
static version: string;
static outputFixes(results: ESLint.LintResult[]): Promise<void>;
static getErrorResults(results: ESLint.LintResult[]): ESLint.LintResult[];
constructor(options: ESLint.Options);
lintFiles(patterns: string | string[]): Promise<ESLint.LintResult[]>;
lintText(code: string, options?: { filePath?: string; warnIgnored?: boolean }): Promise<ESLint.LintResult[]>;
calculateConfigForFile(filePath: string): Promise<any>;
isPathIgnored(filePath: string): Promise<boolean>;
loadFormatter(nameOrPath?: string): Promise<ESLint.Formatter>;
}
export namespace ESLint {
interface Options {
// File enumeration
cwd?: string;
errorOnUnmatchedPattern?: boolean;
extensions?: string[];
globInputPaths?: boolean;
ignore?: boolean;
ignorePath?: string;
// Linting
allowInlineConfig?: boolean;
baseConfig?: Linter.Config;
overrideConfig?: Linter.Config;
overrideConfigFile?: string;
plugins?: Record<string, any>;
reportUnusedDisableDirectives?: Linter.RuleLevel;
resolvePluginsRelativeTo?: string;
rulePaths?: string[];
useEslintrc?: boolean;
// Autofix
fix?: boolean | ((message: Linter.LintMessage) => boolean);
fixTypes?: Array<Rule.RuleMetaData['type']>;
// Cache-related
cache?: boolean;
cacheLocation?: string;
}
interface LintResult {
filePath: string;
messages: Linter.LintMessage[];
errorCount: number;
warningCount: number;
fixableErrorCount: number;
fixableWarningCount: number;
output?: string;
source?: string;
usedDeprecatedRules: DeprecatedRuleUse[];
}
interface LintResultData {
rulesMeta: {
[ruleId: string]: Rule.RuleMetaData;
};
}
interface DeprecatedRuleUse {
ruleId: string;
replacedBy: string[];
}
interface Formatter {
format(results: LintResult[], data?: LintResultData): string;
}
// Docs reference the type by this name
type EditInfo = Rule.Fix;
}
//#endregion
//#region CLIEngine
/** @deprecated Deprecated in favor of `ESLint` */
export class CLIEngine {
static version: string;
constructor(options: CLIEngine.Options);
executeOnFiles(patterns: string[]): CLIEngine.LintReport;
resolveFileGlobPatterns(patterns: string[]): string[];
getConfigForFile(filePath: string): Linter.Config;
executeOnText(text: string, filename?: string): CLIEngine.LintReport;
addPlugin(name: string, pluginObject: any): void;
isPathIgnored(filePath: string): boolean;
getFormatter(format?: string): CLIEngine.Formatter;
getRules(): Map<string, Rule.RuleModule>;
static getErrorResults(results: CLIEngine.LintResult[]): CLIEngine.LintResult[];
static getFormatter(format?: string): CLIEngine.Formatter;
static outputFixes(report: CLIEngine.LintReport): void;
}
/** @deprecated Deprecated in favor of `ESLint` */
export namespace CLIEngine {
class Options {
allowInlineConfig?: boolean;
baseConfig?: false | { [name: string]: any };
cache?: boolean;
cacheFile?: string;
cacheLocation?: string;
configFile?: string;
cwd?: string;
envs?: string[];
errorOnUnmatchedPattern?: boolean;
extensions?: string[];
fix?: boolean;
globals?: string[];
ignore?: boolean;
ignorePath?: string;
ignorePattern?: string | string[];
useEslintrc?: boolean;
parser?: string;
parserOptions?: Linter.ParserOptions;
plugins?: string[];
resolvePluginsRelativeTo?: string;
rules?: {
[name: string]: Linter.RuleLevel | Linter.RuleLevelAndOptions;
};
rulePaths?: string[];
reportUnusedDisableDirectives?: boolean;
}
type LintResult = ESLint.LintResult;
type LintResultData = ESLint.LintResultData;
interface LintReport {
results: LintResult[];
errorCount: number;
warningCount: number;
fixableErrorCount: number;
fixableWarningCount: number;
usedDeprecatedRules: DeprecatedRuleUse[];
}
type DeprecatedRuleUse = ESLint.DeprecatedRuleUse;
type Formatter = (results: LintResult[], data?: LintResultData) => string;
}
//#endregion
//#region RuleTester
export class RuleTester {
constructor(config?: any);
run(
name: string,
rule: Rule.RuleModule,
tests: {
valid?: Array<string | RuleTester.ValidTestCase>;
invalid?: RuleTester.InvalidTestCase[];
},
): void;
}
export namespace RuleTester {
interface ValidTestCase {
code: string;
options?: any;
filename?: string;
parserOptions?: Linter.ParserOptions;
settings?: { [name: string]: any };
parser?: string;
globals?: { [name: string]: boolean };
}
interface SuggestionOutput {
messageId?: string;
desc?: string;
data?: Record<string, unknown>;
output: string;
}
interface InvalidTestCase extends ValidTestCase {
errors: number | Array<TestCaseError | string>;
output?: string | null;
}
interface TestCaseError {
message?: string | RegExp;
messageId?: string;
type?: string;
data?: any;
line?: number;
column?: number;
endLine?: number;
endColumn?: number;
suggestions?: SuggestionOutput[];
}
}
//#endregion

View File

@ -1,24 +0,0 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"dom",
"es6"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../../",
"typeRoots": [
"../../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.d.ts",
"eslint-tests.ts"
]
}

View File

@ -1 +0,0 @@
{ "extends": "dtslint/dt.json" }

View File

@ -2,6 +2,7 @@
"compilerOptions": {
"module": "commonjs",
"lib": [
"dom",
"es6"
],
"noImplicitAny": true,