init
This commit is contained in:
Generated
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
"use strict";
|
||||
// NOTE: this file is isolated to be shared across legacy and flat configs
|
||||
// it is exported via `./use-at-your-own-risk/eslint-recommended-raw`
|
||||
// and it has types manually defined in `./eslint-recommended-raw.d.ts`
|
||||
/**
|
||||
* This is a compatibility ruleset that:
|
||||
* - disables rules from eslint:recommended which are already handled by TypeScript.
|
||||
* - enables rules that make sense due to TS's typechecking / transpilation.
|
||||
*/
|
||||
const config = (style) => ({
|
||||
files: style === 'glob'
|
||||
? // classic configs use glob syntax
|
||||
['*.ts', '*.tsx', '*.mts', '*.cts']
|
||||
: // flat configs use minimatch syntax
|
||||
['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'],
|
||||
rules: {
|
||||
'constructor-super': 'off', // ts(2335) & ts(2377)
|
||||
'getter-return': 'off', // ts(2378)
|
||||
'no-class-assign': 'off', // ts(2629)
|
||||
'no-const-assign': 'off', // ts(2588)
|
||||
'no-dupe-args': 'off', // ts(2300)
|
||||
'no-dupe-class-members': 'off', // ts(2393) & ts(2300)
|
||||
'no-dupe-keys': 'off', // ts(1117)
|
||||
'no-func-assign': 'off', // ts(2630)
|
||||
'no-import-assign': 'off', // ts(2632) & ts(2540)
|
||||
// TODO - remove this once we no longer support ESLint v8
|
||||
'no-new-symbol': 'off', // ts(7009)
|
||||
'no-new-native-nonconstructor': 'off', // ts(7009)
|
||||
'no-obj-calls': 'off', // ts(2349)
|
||||
'no-redeclare': 'off', // ts(2451)
|
||||
'no-setter-return': 'off', // ts(2408)
|
||||
'no-this-before-super': 'off', // ts(2376) & ts(17009)
|
||||
'no-undef': 'off', // ts(2304) & ts(2552)
|
||||
'no-unreachable': 'off', // ts(7027)
|
||||
'no-unsafe-negation': 'off', // ts(2365) & ts(2322) & ts(2358)
|
||||
'no-var': 'error', // ts transpiles let/const to var, so no need for vars any more
|
||||
'prefer-const': 'error', // ts provides better types with const
|
||||
'prefer-rest-params': 'error', // ts provides better types with rest args over arguments
|
||||
'prefer-spread': 'error', // ts transpiles spread to apply, so no need for manual apply
|
||||
},
|
||||
});
|
||||
module.exports = config;
|
||||
//# sourceMappingURL=eslint-recommended-raw.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"eslint-recommended-raw.js","sourceRoot":"","sources":["../../src/configs/eslint-recommended-raw.ts"],"names":[],"mappings":";AAAA,0EAA0E;AAC1E,qEAAqE;AACrE,uEAAuE;AAEvE;;;;GAIG;AACH,MAAM,MAAM,GAAG,CACb,KAA2B,EAI3B,EAAE,CAAC,CAAC;IACJ,KAAK,EACH,KAAK,KAAK,MAAM;QACd,CAAC,CAAC,kCAAkC;YAClC,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;QACrC,CAAC,CAAC,oCAAoC;YACpC,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC;IACrD,KAAK,EAAE;QACL,mBAAmB,EAAE,KAAK,EAAE,sBAAsB;QAClD,eAAe,EAAE,KAAK,EAAE,WAAW;QACnC,iBAAiB,EAAE,KAAK,EAAE,WAAW;QACrC,iBAAiB,EAAE,KAAK,EAAE,WAAW;QACrC,cAAc,EAAE,KAAK,EAAE,WAAW;QAClC,uBAAuB,EAAE,KAAK,EAAE,sBAAsB;QACtD,cAAc,EAAE,KAAK,EAAE,WAAW;QAClC,gBAAgB,EAAE,KAAK,EAAE,WAAW;QACpC,kBAAkB,EAAE,KAAK,EAAE,sBAAsB;QACjD,yDAAyD;QACzD,eAAe,EAAE,KAAK,EAAE,WAAW;QACnC,8BAA8B,EAAE,KAAK,EAAE,WAAW;QAClD,cAAc,EAAE,KAAK,EAAE,WAAW;QAClC,cAAc,EAAE,KAAK,EAAE,WAAW;QAClC,kBAAkB,EAAE,KAAK,EAAE,WAAW;QACtC,sBAAsB,EAAE,KAAK,EAAE,uBAAuB;QACtD,UAAU,EAAE,KAAK,EAAE,sBAAsB;QACzC,gBAAgB,EAAE,KAAK,EAAE,WAAW;QACpC,oBAAoB,EAAE,KAAK,EAAE,iCAAiC;QAC9D,QAAQ,EAAE,OAAO,EAAE,+DAA+D;QAClF,cAAc,EAAE,OAAO,EAAE,sCAAsC;QAC/D,oBAAoB,EAAE,OAAO,EAAE,yDAAyD;QACxF,eAAe,EAAE,OAAO,EAAE,6DAA6D;KACxF;CACF,CAAC,CAAC;AAEH,iBAAS,MAAM,CAAC"}
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tsutils = __importStar(require("ts-api-utils"));
|
||||
const util_1 = require("../util");
|
||||
const getForStatementHeadLoc_1 = require("../util/getForStatementHeadLoc");
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'await-thenable',
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Disallow awaiting a value that is not a Thenable',
|
||||
recommended: 'recommended',
|
||||
requiresTypeChecking: true,
|
||||
},
|
||||
hasSuggestions: true,
|
||||
messages: {
|
||||
await: 'Unexpected `await` of a non-Promise (non-"Thenable") value.',
|
||||
awaitUsingOfNonAsyncDisposable: 'Unexpected `await using` of a value that is not async disposable.',
|
||||
convertToOrdinaryFor: 'Convert to an ordinary `for...of` loop.',
|
||||
forAwaitOfNonAsyncIterable: 'Unexpected `for await...of` of a value that is not async iterable.',
|
||||
removeAwait: 'Remove unnecessary `await`.',
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
defaultOptions: [],
|
||||
create(context) {
|
||||
const services = (0, util_1.getParserServices)(context);
|
||||
const checker = services.program.getTypeChecker();
|
||||
return {
|
||||
AwaitExpression(node) {
|
||||
const type = services.getTypeAtLocation(node.argument);
|
||||
if ((0, util_1.isTypeAnyType)(type) || (0, util_1.isTypeUnknownType)(type)) {
|
||||
return;
|
||||
}
|
||||
const originalNode = services.esTreeNodeToTSNodeMap.get(node);
|
||||
if (!tsutils.isThenableType(checker, originalNode.expression, type)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'await',
|
||||
suggest: [
|
||||
{
|
||||
messageId: 'removeAwait',
|
||||
fix(fixer) {
|
||||
const awaitKeyword = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isAwaitKeyword), util_1.NullThrowsReasons.MissingToken('await', 'await expression'));
|
||||
return fixer.remove(awaitKeyword);
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
},
|
||||
'ForOfStatement[await=true]'(node) {
|
||||
const type = services.getTypeAtLocation(node.right);
|
||||
if ((0, util_1.isTypeAnyType)(type)) {
|
||||
return;
|
||||
}
|
||||
const hasAsyncIteratorSymbol = tsutils
|
||||
.unionTypeParts(type)
|
||||
.some(typePart => tsutils.getWellKnownSymbolPropertyOfType(typePart, 'asyncIterator', checker) != null);
|
||||
if (!hasAsyncIteratorSymbol) {
|
||||
context.report({
|
||||
loc: (0, getForStatementHeadLoc_1.getForStatementHeadLoc)(context.sourceCode, node),
|
||||
messageId: 'forAwaitOfNonAsyncIterable',
|
||||
suggest: [
|
||||
// Note that this suggestion causes broken code for sync iterables
|
||||
// of promises, since the loop variable is not awaited.
|
||||
{
|
||||
messageId: 'convertToOrdinaryFor',
|
||||
fix(fixer) {
|
||||
const awaitToken = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isAwaitKeyword), util_1.NullThrowsReasons.MissingToken('await', 'for await loop'));
|
||||
return fixer.remove(awaitToken);
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
},
|
||||
'VariableDeclaration[kind="await using"]'(node) {
|
||||
for (const declarator of node.declarations) {
|
||||
const init = declarator.init;
|
||||
if (init == null) {
|
||||
continue;
|
||||
}
|
||||
const type = services.getTypeAtLocation(init);
|
||||
if ((0, util_1.isTypeAnyType)(type)) {
|
||||
continue;
|
||||
}
|
||||
const hasAsyncDisposeSymbol = tsutils
|
||||
.unionTypeParts(type)
|
||||
.some(typePart => tsutils.getWellKnownSymbolPropertyOfType(typePart, 'asyncDispose', checker) != null);
|
||||
if (!hasAsyncDisposeSymbol) {
|
||||
context.report({
|
||||
node: init,
|
||||
messageId: 'awaitUsingOfNonAsyncDisposable',
|
||||
// let the user figure out what to do if there's
|
||||
// await using a = b, c = d, e = f;
|
||||
// it's rare and not worth the complexity to handle.
|
||||
...(0, util_1.getFixOrSuggest)({
|
||||
fixOrSuggest: node.declarations.length === 1 ? 'suggest' : 'none',
|
||||
suggestion: {
|
||||
messageId: 'removeAwait',
|
||||
fix(fixer) {
|
||||
const awaitToken = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isAwaitKeyword), util_1.NullThrowsReasons.MissingToken('await', 'await using'));
|
||||
return fixer.remove(awaitToken);
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
//# sourceMappingURL=await-thenable.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"await-thenable.js","sourceRoot":"","sources":["../../src/rules/await-thenable.ts"],"names":[],"mappings":"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"}
|
||||
Generated
Vendored
+101
@@ -0,0 +1,101 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
const util_1 = require("../util");
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'consistent-type-definitions',
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'Enforce type definitions to consistently use either `interface` or `type`',
|
||||
recommended: 'stylistic',
|
||||
},
|
||||
fixable: 'code',
|
||||
messages: {
|
||||
interfaceOverType: 'Use an `interface` instead of a `type`.',
|
||||
typeOverInterface: 'Use a `type` instead of an `interface`.',
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'string',
|
||||
description: 'Which type definition syntax to prefer.',
|
||||
enum: ['interface', 'type'],
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultOptions: ['interface'],
|
||||
create(context, [option]) {
|
||||
/**
|
||||
* Iterates from the highest parent to the currently traversed node
|
||||
* to determine whether any node in tree is globally declared module declaration
|
||||
*/
|
||||
function isCurrentlyTraversedNodeWithinModuleDeclaration(node) {
|
||||
return context.sourceCode
|
||||
.getAncestors(node)
|
||||
.some(node => node.type === utils_1.AST_NODE_TYPES.TSModuleDeclaration &&
|
||||
node.declare &&
|
||||
node.kind === 'global');
|
||||
}
|
||||
return {
|
||||
...(option === 'interface' && {
|
||||
"TSTypeAliasDeclaration[typeAnnotation.type='TSTypeLiteral']"(node) {
|
||||
context.report({
|
||||
node: node.id,
|
||||
messageId: 'interfaceOverType',
|
||||
fix(fixer) {
|
||||
const typeToken = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(node.id, token => token.value === 'type'), util_1.NullThrowsReasons.MissingToken('type keyword', 'type alias'));
|
||||
const equalsToken = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(node.typeAnnotation, token => token.value === '='), util_1.NullThrowsReasons.MissingToken('=', 'type alias'));
|
||||
const beforeEqualsToken = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(equalsToken, {
|
||||
includeComments: true,
|
||||
}), util_1.NullThrowsReasons.MissingToken('before =', 'type alias'));
|
||||
return [
|
||||
// replace 'type' with 'interface'.
|
||||
fixer.replaceText(typeToken, 'interface'),
|
||||
// delete from the = to the { of the type, and put a space to be pretty.
|
||||
fixer.replaceTextRange([beforeEqualsToken.range[1], node.typeAnnotation.range[0]], ' '),
|
||||
// remove from the closing } through the end of the statement.
|
||||
fixer.removeRange([
|
||||
node.typeAnnotation.range[1],
|
||||
node.range[1],
|
||||
]),
|
||||
];
|
||||
},
|
||||
});
|
||||
},
|
||||
}),
|
||||
...(option === 'type' && {
|
||||
TSInterfaceDeclaration(node) {
|
||||
const fix = isCurrentlyTraversedNodeWithinModuleDeclaration(node)
|
||||
? null
|
||||
: (fixer) => {
|
||||
const typeNode = node.typeParameters ?? node.id;
|
||||
const fixes = [];
|
||||
const firstToken = context.sourceCode.getTokenBefore(node.id);
|
||||
if (firstToken) {
|
||||
fixes.push(fixer.replaceText(firstToken, 'type'));
|
||||
fixes.push(fixer.replaceTextRange([typeNode.range[1], node.body.range[0]], ' = '));
|
||||
}
|
||||
node.extends.forEach(heritage => {
|
||||
const typeIdentifier = context.sourceCode.getText(heritage);
|
||||
fixes.push(fixer.insertTextAfter(node.body, ` & ${typeIdentifier}`));
|
||||
});
|
||||
if (node.parent.type === utils_1.AST_NODE_TYPES.ExportDefaultDeclaration) {
|
||||
fixes.push(fixer.removeRange([node.parent.range[0], node.range[0]]), fixer.insertTextAfter(node.body, `\nexport default ${node.id.name}`));
|
||||
}
|
||||
return fixes;
|
||||
};
|
||||
context.report({
|
||||
node: node.id,
|
||||
messageId: 'typeOverInterface',
|
||||
/**
|
||||
* remove automatically fix when the interface is within a declare global
|
||||
* @see {@link https://github.com/typescript-eslint/typescript-eslint/issues/2707}
|
||||
*/
|
||||
fix,
|
||||
});
|
||||
},
|
||||
}),
|
||||
};
|
||||
},
|
||||
});
|
||||
//# sourceMappingURL=consistent-type-definitions.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"consistent-type-definitions.js","sourceRoot":"","sources":["../../src/rules/consistent-type-definitions.ts"],"names":[],"mappings":"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"}
|
||||
Generated
Vendored
+344
@@ -0,0 +1,344 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
const tsutils = __importStar(require("ts-api-utils"));
|
||||
const ts = __importStar(require("typescript"));
|
||||
const util_1 = require("../util");
|
||||
const getParentFunctionNode_1 = require("../util/getParentFunctionNode");
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'no-confusing-void-expression',
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Require expressions of type void to appear in statement position',
|
||||
recommended: 'strict',
|
||||
requiresTypeChecking: true,
|
||||
},
|
||||
fixable: 'code',
|
||||
hasSuggestions: true,
|
||||
messages: {
|
||||
invalidVoidExpr: 'Placing a void expression inside another expression is forbidden. ' +
|
||||
'Move it to its own statement instead.',
|
||||
invalidVoidExprArrow: 'Returning a void expression from an arrow function shorthand is forbidden. ' +
|
||||
'Please add braces to the arrow function.',
|
||||
invalidVoidExprArrowWrapVoid: 'Void expressions returned from an arrow function shorthand ' +
|
||||
'must be marked explicitly with the `void` operator.',
|
||||
invalidVoidExprReturn: 'Returning a void expression from a function is forbidden. ' +
|
||||
'Please move it before the `return` statement.',
|
||||
invalidVoidExprReturnLast: 'Returning a void expression from a function is forbidden. ' +
|
||||
'Please remove the `return` statement.',
|
||||
invalidVoidExprReturnWrapVoid: 'Void expressions returned from a function ' +
|
||||
'must be marked explicitly with the `void` operator.',
|
||||
invalidVoidExprWrapVoid: 'Void expressions used inside another expression ' +
|
||||
'must be moved to its own statement ' +
|
||||
'or marked explicitly with the `void` operator.',
|
||||
voidExprWrapVoid: 'Mark with an explicit `void` operator.',
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
ignoreArrowShorthand: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to ignore "shorthand" `() =>` arrow functions: those without `{ ... }` braces.',
|
||||
},
|
||||
ignoreVoidOperator: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to ignore returns that start with the `void` operator.',
|
||||
},
|
||||
ignoreVoidReturningFunctions: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to ignore returns from functions with explicit `void` return types and functions with contextual `void` return types.',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultOptions: [{ ignoreArrowShorthand: false, ignoreVoidOperator: false }],
|
||||
create(context, [options]) {
|
||||
const services = (0, util_1.getParserServices)(context);
|
||||
const checker = services.program.getTypeChecker();
|
||||
return {
|
||||
'AwaitExpression, CallExpression, TaggedTemplateExpression'(node) {
|
||||
const type = (0, util_1.getConstrainedTypeAtLocation)(services, node);
|
||||
if (!tsutils.isTypeFlagSet(type, ts.TypeFlags.VoidLike)) {
|
||||
// not a void expression
|
||||
return;
|
||||
}
|
||||
const invalidAncestor = findInvalidAncestor(node);
|
||||
if (invalidAncestor == null) {
|
||||
// void expression is in valid position
|
||||
return;
|
||||
}
|
||||
const wrapVoidFix = (fixer) => {
|
||||
const nodeText = context.sourceCode.getText(node);
|
||||
const newNodeText = `void ${nodeText}`;
|
||||
return fixer.replaceText(node, newNodeText);
|
||||
};
|
||||
if (invalidAncestor.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression) {
|
||||
// handle arrow function shorthand
|
||||
if (options.ignoreVoidReturningFunctions) {
|
||||
const returnsVoid = isVoidReturningFunctionNode(invalidAncestor);
|
||||
if (returnsVoid) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (options.ignoreVoidOperator) {
|
||||
// handle wrapping with `void`
|
||||
return context.report({
|
||||
node,
|
||||
messageId: 'invalidVoidExprArrowWrapVoid',
|
||||
fix: wrapVoidFix,
|
||||
});
|
||||
}
|
||||
// handle wrapping with braces
|
||||
const arrowFunction = invalidAncestor;
|
||||
return context.report({
|
||||
node,
|
||||
messageId: 'invalidVoidExprArrow',
|
||||
fix(fixer) {
|
||||
if (!canFix(arrowFunction)) {
|
||||
return null;
|
||||
}
|
||||
const arrowBody = arrowFunction.body;
|
||||
const arrowBodyText = context.sourceCode.getText(arrowBody);
|
||||
const newArrowBodyText = `{ ${arrowBodyText}; }`;
|
||||
if ((0, util_1.isParenthesized)(arrowBody, context.sourceCode)) {
|
||||
const bodyOpeningParen = (0, util_1.nullThrows)(context.sourceCode.getTokenBefore(arrowBody, util_1.isOpeningParenToken), util_1.NullThrowsReasons.MissingToken('opening parenthesis', 'arrow body'));
|
||||
const bodyClosingParen = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(arrowBody, util_1.isClosingParenToken), util_1.NullThrowsReasons.MissingToken('closing parenthesis', 'arrow body'));
|
||||
return fixer.replaceTextRange([bodyOpeningParen.range[0], bodyClosingParen.range[1]], newArrowBodyText);
|
||||
}
|
||||
return fixer.replaceText(arrowBody, newArrowBodyText);
|
||||
},
|
||||
});
|
||||
}
|
||||
if (invalidAncestor.type === utils_1.AST_NODE_TYPES.ReturnStatement) {
|
||||
// handle return statement
|
||||
if (options.ignoreVoidReturningFunctions) {
|
||||
const functionNode = (0, getParentFunctionNode_1.getParentFunctionNode)(invalidAncestor);
|
||||
if (functionNode) {
|
||||
const returnsVoid = isVoidReturningFunctionNode(functionNode);
|
||||
if (returnsVoid) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.ignoreVoidOperator) {
|
||||
// handle wrapping with `void`
|
||||
return context.report({
|
||||
node,
|
||||
messageId: 'invalidVoidExprReturnWrapVoid',
|
||||
fix: wrapVoidFix,
|
||||
});
|
||||
}
|
||||
if (isFinalReturn(invalidAncestor)) {
|
||||
// remove the `return` keyword
|
||||
return context.report({
|
||||
node,
|
||||
messageId: 'invalidVoidExprReturnLast',
|
||||
fix(fixer) {
|
||||
if (!canFix(invalidAncestor)) {
|
||||
return null;
|
||||
}
|
||||
const returnValue = invalidAncestor.argument;
|
||||
const returnValueText = context.sourceCode.getText(returnValue);
|
||||
let newReturnStmtText = `${returnValueText};`;
|
||||
if (isPreventingASI(returnValue)) {
|
||||
// put a semicolon at the beginning of the line
|
||||
newReturnStmtText = `;${newReturnStmtText}`;
|
||||
}
|
||||
return fixer.replaceText(invalidAncestor, newReturnStmtText);
|
||||
},
|
||||
});
|
||||
}
|
||||
// move before the `return` keyword
|
||||
return context.report({
|
||||
node,
|
||||
messageId: 'invalidVoidExprReturn',
|
||||
fix(fixer) {
|
||||
const returnValue = invalidAncestor.argument;
|
||||
const returnValueText = context.sourceCode.getText(returnValue);
|
||||
let newReturnStmtText = `${returnValueText}; return;`;
|
||||
if (isPreventingASI(returnValue)) {
|
||||
// put a semicolon at the beginning of the line
|
||||
newReturnStmtText = `;${newReturnStmtText}`;
|
||||
}
|
||||
if (invalidAncestor.parent.type !== utils_1.AST_NODE_TYPES.BlockStatement) {
|
||||
// e.g. `if (cond) return console.error();`
|
||||
// add braces if not inside a block
|
||||
newReturnStmtText = `{ ${newReturnStmtText} }`;
|
||||
}
|
||||
return fixer.replaceText(invalidAncestor, newReturnStmtText);
|
||||
},
|
||||
});
|
||||
}
|
||||
// handle generic case
|
||||
if (options.ignoreVoidOperator) {
|
||||
// this would be reported by this rule btw. such irony
|
||||
return context.report({
|
||||
node,
|
||||
messageId: 'invalidVoidExprWrapVoid',
|
||||
suggest: [{ messageId: 'voidExprWrapVoid', fix: wrapVoidFix }],
|
||||
});
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'invalidVoidExpr',
|
||||
});
|
||||
},
|
||||
};
|
||||
/**
|
||||
* Inspects the void expression's ancestors and finds closest invalid one.
|
||||
* By default anything other than an ExpressionStatement is invalid.
|
||||
* Parent expressions which can be used for their short-circuiting behavior
|
||||
* are ignored and their parents are checked instead.
|
||||
* @param node The void expression node to check.
|
||||
* @returns Invalid ancestor node if it was found. `null` otherwise.
|
||||
*/
|
||||
function findInvalidAncestor(node) {
|
||||
const parent = (0, util_1.nullThrows)(node.parent, util_1.NullThrowsReasons.MissingParent);
|
||||
if (parent.type === utils_1.AST_NODE_TYPES.SequenceExpression &&
|
||||
node !== parent.expressions[parent.expressions.length - 1]) {
|
||||
return null;
|
||||
}
|
||||
if (parent.type === utils_1.AST_NODE_TYPES.ExpressionStatement) {
|
||||
// e.g. `{ console.log("foo"); }`
|
||||
// this is always valid
|
||||
return null;
|
||||
}
|
||||
if (parent.type === utils_1.AST_NODE_TYPES.LogicalExpression &&
|
||||
parent.right === node) {
|
||||
// e.g. `x && console.log(x)`
|
||||
// this is valid only if the next ancestor is valid
|
||||
return findInvalidAncestor(parent);
|
||||
}
|
||||
if (parent.type === utils_1.AST_NODE_TYPES.ConditionalExpression &&
|
||||
(parent.consequent === node || parent.alternate === node)) {
|
||||
// e.g. `cond ? console.log(true) : console.log(false)`
|
||||
// this is valid only if the next ancestor is valid
|
||||
return findInvalidAncestor(parent);
|
||||
}
|
||||
if (parent.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression &&
|
||||
// e.g. `() => console.log("foo")`
|
||||
// this is valid with an appropriate option
|
||||
options.ignoreArrowShorthand) {
|
||||
return null;
|
||||
}
|
||||
if (parent.type === utils_1.AST_NODE_TYPES.UnaryExpression &&
|
||||
parent.operator === 'void' &&
|
||||
// e.g. `void console.log("foo")`
|
||||
// this is valid with an appropriate option
|
||||
options.ignoreVoidOperator) {
|
||||
return null;
|
||||
}
|
||||
if (parent.type === utils_1.AST_NODE_TYPES.ChainExpression) {
|
||||
// e.g. `console?.log('foo')`
|
||||
return findInvalidAncestor(parent);
|
||||
}
|
||||
// Any other parent is invalid.
|
||||
// We can assume a return statement will have an argument.
|
||||
return parent;
|
||||
}
|
||||
/** Checks whether the return statement is the last statement in a function body. */
|
||||
function isFinalReturn(node) {
|
||||
// the parent must be a block
|
||||
const block = (0, util_1.nullThrows)(node.parent, util_1.NullThrowsReasons.MissingParent);
|
||||
if (block.type !== utils_1.AST_NODE_TYPES.BlockStatement) {
|
||||
// e.g. `if (cond) return;` (not in a block)
|
||||
return false;
|
||||
}
|
||||
// the block's parent must be a function
|
||||
const blockParent = (0, util_1.nullThrows)(block.parent, util_1.NullThrowsReasons.MissingParent);
|
||||
if (![
|
||||
utils_1.AST_NODE_TYPES.ArrowFunctionExpression,
|
||||
utils_1.AST_NODE_TYPES.FunctionDeclaration,
|
||||
utils_1.AST_NODE_TYPES.FunctionExpression,
|
||||
].includes(blockParent.type)) {
|
||||
// e.g. `if (cond) { return; }`
|
||||
// not in a top-level function block
|
||||
return false;
|
||||
}
|
||||
// must be the last child of the block
|
||||
if (block.body.indexOf(node) < block.body.length - 1) {
|
||||
// not the last statement in the block
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Checks whether the given node, if placed on its own line,
|
||||
* would prevent automatic semicolon insertion on the line before.
|
||||
*
|
||||
* This happens if the line begins with `(`, `[` or `` ` ``
|
||||
*/
|
||||
function isPreventingASI(node) {
|
||||
const startToken = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node), util_1.NullThrowsReasons.MissingToken('first token', node.type));
|
||||
return ['(', '[', '`'].includes(startToken.value);
|
||||
}
|
||||
function canFix(node) {
|
||||
const targetNode = node.type === utils_1.AST_NODE_TYPES.ReturnStatement
|
||||
? node.argument
|
||||
: node.body;
|
||||
const type = (0, util_1.getConstrainedTypeAtLocation)(services, targetNode);
|
||||
return tsutils.isTypeFlagSet(type, ts.TypeFlags.VoidLike);
|
||||
}
|
||||
function isFunctionReturnTypeIncludesVoid(functionType) {
|
||||
const callSignatures = tsutils.getCallSignaturesOfType(functionType);
|
||||
return callSignatures.some(signature => {
|
||||
const returnType = signature.getReturnType();
|
||||
return tsutils
|
||||
.unionTypeParts(returnType)
|
||||
.some(tsutils.isIntrinsicVoidType);
|
||||
});
|
||||
}
|
||||
function isVoidReturningFunctionNode(functionNode) {
|
||||
// Game plan:
|
||||
// - If the function node has a type annotation, check if it includes `void`.
|
||||
// - If it does then the function is safe to return `void` expressions in.
|
||||
// - Otherwise, check if the function is a function-expression or an arrow-function.
|
||||
// - If it is, get its contextual type and bail if we cannot.
|
||||
// - Return based on whether the contextual type includes `void` or not
|
||||
const functionTSNode = services.esTreeNodeToTSNodeMap.get(functionNode);
|
||||
if (functionTSNode.type) {
|
||||
const returnType = checker.getTypeFromTypeNode(functionTSNode.type);
|
||||
return tsutils
|
||||
.unionTypeParts(returnType)
|
||||
.some(tsutils.isIntrinsicVoidType);
|
||||
}
|
||||
if (ts.isExpression(functionTSNode)) {
|
||||
const functionType = checker.getContextualType(functionTSNode);
|
||||
if (functionType) {
|
||||
return tsutils
|
||||
.unionTypeParts(functionType)
|
||||
.some(isFunctionReturnTypeIncludesVoid);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
});
|
||||
//# sourceMappingURL=no-confusing-void-expression.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
+277
@@ -0,0 +1,277 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
const tsutils = __importStar(require("ts-api-utils"));
|
||||
const ts = __importStar(require("typescript"));
|
||||
const util_1 = require("../util");
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'no-deprecated',
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Disallow using code marked as `@deprecated`',
|
||||
recommended: 'strict',
|
||||
requiresTypeChecking: true,
|
||||
},
|
||||
messages: {
|
||||
deprecated: `\`{{name}}\` is deprecated.`,
|
||||
deprecatedWithReason: `\`{{name}}\` is deprecated. {{reason}}`,
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
defaultOptions: [],
|
||||
create(context) {
|
||||
const { jsDocParsingMode } = context.parserOptions;
|
||||
if (jsDocParsingMode === 'none' || jsDocParsingMode === 'type-info') {
|
||||
throw new Error(`Cannot be used with jsDocParsingMode: '${jsDocParsingMode}'.`);
|
||||
}
|
||||
const services = (0, util_1.getParserServices)(context);
|
||||
const checker = services.program.getTypeChecker();
|
||||
// Deprecated jsdoc tags can be added on some symbol alias, e.g.
|
||||
//
|
||||
// export { /** @deprecated */ foo }
|
||||
//
|
||||
// When we import foo, its symbol is an alias of the exported foo (the one
|
||||
// with the deprecated tag), which is itself an alias of the original foo.
|
||||
// Therefore, we carefully go through the chain of aliases and check each
|
||||
// immediate alias for deprecated tags
|
||||
function searchForDeprecationInAliasesChain(symbol, checkDeprecationsOfAliasedSymbol) {
|
||||
if (!symbol || !tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias)) {
|
||||
return checkDeprecationsOfAliasedSymbol
|
||||
? getJsDocDeprecation(symbol)
|
||||
: undefined;
|
||||
}
|
||||
const targetSymbol = checker.getAliasedSymbol(symbol);
|
||||
while (tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias)) {
|
||||
const reason = getJsDocDeprecation(symbol);
|
||||
if (reason !== undefined) {
|
||||
return reason;
|
||||
}
|
||||
const immediateAliasedSymbol = symbol.getDeclarations() && checker.getImmediateAliasedSymbol(symbol);
|
||||
if (!immediateAliasedSymbol) {
|
||||
break;
|
||||
}
|
||||
symbol = immediateAliasedSymbol;
|
||||
if (checkDeprecationsOfAliasedSymbol && symbol === targetSymbol) {
|
||||
return getJsDocDeprecation(symbol);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
function isDeclaration(node) {
|
||||
const { parent } = node;
|
||||
switch (parent.type) {
|
||||
case utils_1.AST_NODE_TYPES.ArrayPattern:
|
||||
return parent.elements.includes(node);
|
||||
case utils_1.AST_NODE_TYPES.ClassExpression:
|
||||
case utils_1.AST_NODE_TYPES.ClassDeclaration:
|
||||
case utils_1.AST_NODE_TYPES.VariableDeclarator:
|
||||
case utils_1.AST_NODE_TYPES.TSEnumMember:
|
||||
return parent.id === node;
|
||||
case utils_1.AST_NODE_TYPES.MethodDefinition:
|
||||
case utils_1.AST_NODE_TYPES.PropertyDefinition:
|
||||
return parent.key === node;
|
||||
case utils_1.AST_NODE_TYPES.Property:
|
||||
// foo in "const { foo } = bar" will be processed twice, as parent.key
|
||||
// and parent.value. The second is treated as a declaration.
|
||||
return ((parent.shorthand && parent.value === node) ||
|
||||
parent.parent.type === utils_1.AST_NODE_TYPES.ObjectExpression);
|
||||
case utils_1.AST_NODE_TYPES.AssignmentPattern:
|
||||
// foo in "const { foo = "" } = bar" will be processed twice, as parent.parent.key
|
||||
// and parent.left. The second is treated as a declaration.
|
||||
return parent.left === node;
|
||||
case utils_1.AST_NODE_TYPES.ArrowFunctionExpression:
|
||||
case utils_1.AST_NODE_TYPES.FunctionDeclaration:
|
||||
case utils_1.AST_NODE_TYPES.FunctionExpression:
|
||||
case utils_1.AST_NODE_TYPES.TSDeclareFunction:
|
||||
case utils_1.AST_NODE_TYPES.TSEmptyBodyFunctionExpression:
|
||||
case utils_1.AST_NODE_TYPES.TSEnumDeclaration:
|
||||
case utils_1.AST_NODE_TYPES.TSInterfaceDeclaration:
|
||||
case utils_1.AST_NODE_TYPES.TSMethodSignature:
|
||||
case utils_1.AST_NODE_TYPES.TSModuleDeclaration:
|
||||
case utils_1.AST_NODE_TYPES.TSParameterProperty:
|
||||
case utils_1.AST_NODE_TYPES.TSPropertySignature:
|
||||
case utils_1.AST_NODE_TYPES.TSTypeAliasDeclaration:
|
||||
case utils_1.AST_NODE_TYPES.TSTypeParameter:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function isInsideExportOrImport(node) {
|
||||
let current = node;
|
||||
while (true) {
|
||||
switch (current.type) {
|
||||
case utils_1.AST_NODE_TYPES.ExportAllDeclaration:
|
||||
case utils_1.AST_NODE_TYPES.ExportDefaultDeclaration:
|
||||
case utils_1.AST_NODE_TYPES.ExportNamedDeclaration:
|
||||
case utils_1.AST_NODE_TYPES.ImportDeclaration:
|
||||
return true;
|
||||
case utils_1.AST_NODE_TYPES.ArrowFunctionExpression:
|
||||
case utils_1.AST_NODE_TYPES.BlockStatement:
|
||||
case utils_1.AST_NODE_TYPES.ClassDeclaration:
|
||||
case utils_1.AST_NODE_TYPES.TSInterfaceDeclaration:
|
||||
case utils_1.AST_NODE_TYPES.FunctionDeclaration:
|
||||
case utils_1.AST_NODE_TYPES.FunctionExpression:
|
||||
case utils_1.AST_NODE_TYPES.Program:
|
||||
case utils_1.AST_NODE_TYPES.TSUnionType:
|
||||
case utils_1.AST_NODE_TYPES.VariableDeclarator:
|
||||
return false;
|
||||
default:
|
||||
current = current.parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
function getJsDocDeprecation(symbol) {
|
||||
let jsDocTags;
|
||||
try {
|
||||
jsDocTags = symbol?.getJsDocTags(checker);
|
||||
}
|
||||
catch {
|
||||
// workaround for https://github.com/microsoft/TypeScript/issues/60024
|
||||
return;
|
||||
}
|
||||
const tag = jsDocTags?.find(tag => tag.name === 'deprecated');
|
||||
if (!tag) {
|
||||
return undefined;
|
||||
}
|
||||
const displayParts = tag.text;
|
||||
return displayParts ? ts.displayPartsToString(displayParts) : '';
|
||||
}
|
||||
function isNodeCalleeOfParent(node) {
|
||||
switch (node.parent?.type) {
|
||||
case utils_1.AST_NODE_TYPES.NewExpression:
|
||||
case utils_1.AST_NODE_TYPES.CallExpression:
|
||||
return node.parent.callee === node;
|
||||
case utils_1.AST_NODE_TYPES.TaggedTemplateExpression:
|
||||
return node.parent.tag === node;
|
||||
case utils_1.AST_NODE_TYPES.JSXOpeningElement:
|
||||
return node.parent.name === node;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function getCallLikeNode(node) {
|
||||
let callee = node;
|
||||
while (callee.parent?.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
||||
callee.parent.property === callee) {
|
||||
callee = callee.parent;
|
||||
}
|
||||
return isNodeCalleeOfParent(callee) ? callee : undefined;
|
||||
}
|
||||
function getCallLikeDeprecation(node) {
|
||||
const tsNode = services.esTreeNodeToTSNodeMap.get(node.parent);
|
||||
// If the node is a direct function call, we look for its signature.
|
||||
const signature = (0, util_1.nullThrows)(checker.getResolvedSignature(tsNode), 'Expected call like node to have signature');
|
||||
const symbol = services.getSymbolAtLocation(node);
|
||||
const aliasedSymbol = symbol !== undefined &&
|
||||
tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias)
|
||||
? checker.getAliasedSymbol(symbol)
|
||||
: symbol;
|
||||
const symbolDeclarationKind = aliasedSymbol?.declarations?.[0].kind;
|
||||
// Properties with function-like types have "deprecated" jsdoc
|
||||
// on their symbols, not on their signatures:
|
||||
//
|
||||
// interface Props {
|
||||
// /** @deprecated */
|
||||
// property: () => 'foo'
|
||||
// ^symbol^ ^signature^
|
||||
// }
|
||||
if (symbolDeclarationKind !== ts.SyntaxKind.MethodDeclaration &&
|
||||
symbolDeclarationKind !== ts.SyntaxKind.FunctionDeclaration &&
|
||||
symbolDeclarationKind !== ts.SyntaxKind.MethodSignature) {
|
||||
return (searchForDeprecationInAliasesChain(symbol, true) ??
|
||||
getJsDocDeprecation(signature) ??
|
||||
getJsDocDeprecation(aliasedSymbol));
|
||||
}
|
||||
return (searchForDeprecationInAliasesChain(symbol,
|
||||
// Here we're working with a function declaration or method.
|
||||
// Both can have 1 or more overloads, each overload creates one
|
||||
// ts.Declaration which is placed in symbol.declarations.
|
||||
//
|
||||
// Imagine the following code:
|
||||
//
|
||||
// function foo(): void
|
||||
// /** @deprecated Some Reason */
|
||||
// function foo(arg: string): void
|
||||
// function foo(arg?: string): void {}
|
||||
//
|
||||
// foo() // <- foo is our symbol
|
||||
//
|
||||
// If we call getJsDocDeprecation(checker.getAliasedSymbol(symbol)),
|
||||
// we get 'Some Reason', but after all, we are calling foo with
|
||||
// a signature that is not deprecated!
|
||||
// It works this way because symbol.getJsDocTags returns tags from
|
||||
// all symbol declarations combined into one array. And AFAIK there is
|
||||
// no publicly exported TS function that can tell us if a particular
|
||||
// declaration is deprecated or not.
|
||||
//
|
||||
// So, in case of function and method declarations, we don't check original
|
||||
// aliased symbol, but rely on the getJsDocDeprecation(signature) call below.
|
||||
false) ?? getJsDocDeprecation(signature));
|
||||
}
|
||||
function getDeprecationReason(node) {
|
||||
const callLikeNode = getCallLikeNode(node);
|
||||
if (callLikeNode) {
|
||||
return getCallLikeDeprecation(callLikeNode);
|
||||
}
|
||||
if (node.parent.type === utils_1.AST_NODE_TYPES.Property) {
|
||||
return getJsDocDeprecation(services.getTypeAtLocation(node.parent.parent).getProperty(node.name));
|
||||
}
|
||||
return searchForDeprecationInAliasesChain(services.getSymbolAtLocation(node), true);
|
||||
}
|
||||
function checkIdentifier(node) {
|
||||
if (isDeclaration(node) || isInsideExportOrImport(node)) {
|
||||
return;
|
||||
}
|
||||
const reason = getDeprecationReason(node);
|
||||
if (reason === undefined) {
|
||||
return;
|
||||
}
|
||||
context.report({
|
||||
...(reason
|
||||
? {
|
||||
messageId: 'deprecatedWithReason',
|
||||
data: { name: node.name, reason },
|
||||
}
|
||||
: {
|
||||
messageId: 'deprecated',
|
||||
data: { name: node.name },
|
||||
}),
|
||||
node,
|
||||
});
|
||||
}
|
||||
return {
|
||||
Identifier: checkIdentifier,
|
||||
JSXIdentifier(node) {
|
||||
if (node.parent.type !== utils_1.AST_NODE_TYPES.JSXClosingElement) {
|
||||
checkIdentifier(node);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
//# sourceMappingURL=no-deprecated.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+743
@@ -0,0 +1,743 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
const tsutils = __importStar(require("ts-api-utils"));
|
||||
const ts = __importStar(require("typescript"));
|
||||
const util_1 = require("../util");
|
||||
function parseChecksVoidReturn(checksVoidReturn) {
|
||||
switch (checksVoidReturn) {
|
||||
case false:
|
||||
return false;
|
||||
case true:
|
||||
case undefined:
|
||||
return {
|
||||
arguments: true,
|
||||
attributes: true,
|
||||
inheritedMethods: true,
|
||||
properties: true,
|
||||
returns: true,
|
||||
variables: true,
|
||||
};
|
||||
default:
|
||||
return {
|
||||
arguments: checksVoidReturn.arguments ?? true,
|
||||
attributes: checksVoidReturn.attributes ?? true,
|
||||
inheritedMethods: checksVoidReturn.inheritedMethods ?? true,
|
||||
properties: checksVoidReturn.properties ?? true,
|
||||
returns: checksVoidReturn.returns ?? true,
|
||||
variables: checksVoidReturn.variables ?? true,
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'no-misused-promises',
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Disallow Promises in places not designed to handle them',
|
||||
recommended: 'recommended',
|
||||
requiresTypeChecking: true,
|
||||
},
|
||||
messages: {
|
||||
conditional: 'Expected non-Promise value in a boolean conditional.',
|
||||
predicate: 'Expected a non-Promise value to be returned.',
|
||||
spread: 'Expected a non-Promise value to be spreaded in an object.',
|
||||
voidReturnArgument: 'Promise returned in function argument where a void return was expected.',
|
||||
voidReturnAttribute: 'Promise-returning function provided to attribute where a void return was expected.',
|
||||
voidReturnInheritedMethod: "Promise-returning method provided where a void return was expected by extended/implemented type '{{ heritageTypeName }}'.",
|
||||
voidReturnProperty: 'Promise-returning function provided to property where a void return was expected.',
|
||||
voidReturnReturnValue: 'Promise-returning function provided to return value where a void return was expected.',
|
||||
voidReturnVariable: 'Promise-returning function provided to variable where a void return was expected.',
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
checksConditionals: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to warn when a Promise is provided to conditional statements.',
|
||||
},
|
||||
checksSpreads: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to warn when `...` spreading a `Promise`.',
|
||||
},
|
||||
checksVoidReturn: {
|
||||
description: 'Whether to warn when a Promise is returned from a function typed as returning `void`.',
|
||||
oneOf: [
|
||||
{
|
||||
type: 'boolean',
|
||||
description: 'Whether to disable checking all asynchronous functions.',
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
description: 'Which forms of functions may have checking disabled.',
|
||||
properties: {
|
||||
arguments: {
|
||||
type: 'boolean',
|
||||
description: 'Disables checking an asynchronous function passed as argument where the parameter type expects a function that returns `void`.',
|
||||
},
|
||||
attributes: {
|
||||
type: 'boolean',
|
||||
description: 'Disables checking an asynchronous function passed as a JSX attribute expected to be a function that returns `void`.',
|
||||
},
|
||||
inheritedMethods: {
|
||||
type: 'boolean',
|
||||
description: 'Disables checking an asynchronous method in a type that extends or implements another type expecting that method to return `void`.',
|
||||
},
|
||||
properties: {
|
||||
type: 'boolean',
|
||||
description: 'Disables checking an asynchronous function passed as an object property expected to be a function that returns `void`.',
|
||||
},
|
||||
returns: {
|
||||
type: 'boolean',
|
||||
description: 'Disables checking an asynchronous function returned in a function whose return type is a function that returns `void`.',
|
||||
},
|
||||
variables: {
|
||||
type: 'boolean',
|
||||
description: 'Disables checking an asynchronous function used as a variable whose return type is a function that returns `void`.',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultOptions: [
|
||||
{
|
||||
checksConditionals: true,
|
||||
checksSpreads: true,
|
||||
checksVoidReturn: true,
|
||||
},
|
||||
],
|
||||
create(context, [{ checksConditionals, checksSpreads, checksVoidReturn }]) {
|
||||
const services = (0, util_1.getParserServices)(context);
|
||||
const checker = services.program.getTypeChecker();
|
||||
const checkedNodes = new Set();
|
||||
const conditionalChecks = {
|
||||
'CallExpression > MemberExpression': checkArrayPredicates,
|
||||
ConditionalExpression: checkTestConditional,
|
||||
DoWhileStatement: checkTestConditional,
|
||||
ForStatement: checkTestConditional,
|
||||
IfStatement: checkTestConditional,
|
||||
LogicalExpression: checkConditional,
|
||||
'UnaryExpression[operator="!"]'(node) {
|
||||
checkConditional(node.argument, true);
|
||||
},
|
||||
WhileStatement: checkTestConditional,
|
||||
};
|
||||
checksVoidReturn = parseChecksVoidReturn(checksVoidReturn);
|
||||
const voidReturnChecks = checksVoidReturn
|
||||
? {
|
||||
...(checksVoidReturn.arguments && {
|
||||
CallExpression: checkArguments,
|
||||
NewExpression: checkArguments,
|
||||
}),
|
||||
...(checksVoidReturn.attributes && {
|
||||
JSXAttribute: checkJSXAttribute,
|
||||
}),
|
||||
...(checksVoidReturn.inheritedMethods && {
|
||||
ClassDeclaration: checkClassLikeOrInterfaceNode,
|
||||
ClassExpression: checkClassLikeOrInterfaceNode,
|
||||
TSInterfaceDeclaration: checkClassLikeOrInterfaceNode,
|
||||
}),
|
||||
...(checksVoidReturn.properties && {
|
||||
Property: checkProperty,
|
||||
}),
|
||||
...(checksVoidReturn.returns && {
|
||||
ReturnStatement: checkReturnStatement,
|
||||
}),
|
||||
...(checksVoidReturn.variables && {
|
||||
AssignmentExpression: checkAssignment,
|
||||
VariableDeclarator: checkVariableDeclaration,
|
||||
}),
|
||||
}
|
||||
: {};
|
||||
const spreadChecks = {
|
||||
SpreadElement: checkSpread,
|
||||
};
|
||||
/**
|
||||
* A syntactic check to see if an annotated type is maybe a function type.
|
||||
* This is a perf optimization to help avoid requesting types where possible
|
||||
*/
|
||||
function isPossiblyFunctionType(node) {
|
||||
switch (node.typeAnnotation.type) {
|
||||
case utils_1.AST_NODE_TYPES.TSConditionalType:
|
||||
case utils_1.AST_NODE_TYPES.TSConstructorType:
|
||||
case utils_1.AST_NODE_TYPES.TSFunctionType:
|
||||
case utils_1.AST_NODE_TYPES.TSImportType:
|
||||
case utils_1.AST_NODE_TYPES.TSIndexedAccessType:
|
||||
case utils_1.AST_NODE_TYPES.TSInferType:
|
||||
case utils_1.AST_NODE_TYPES.TSIntersectionType:
|
||||
case utils_1.AST_NODE_TYPES.TSQualifiedName:
|
||||
case utils_1.AST_NODE_TYPES.TSThisType:
|
||||
case utils_1.AST_NODE_TYPES.TSTypeOperator:
|
||||
case utils_1.AST_NODE_TYPES.TSTypeQuery:
|
||||
case utils_1.AST_NODE_TYPES.TSTypeReference:
|
||||
case utils_1.AST_NODE_TYPES.TSUnionType:
|
||||
return true;
|
||||
case utils_1.AST_NODE_TYPES.TSTypeLiteral:
|
||||
return node.typeAnnotation.members.some(member => member.type === utils_1.AST_NODE_TYPES.TSCallSignatureDeclaration ||
|
||||
member.type === utils_1.AST_NODE_TYPES.TSConstructSignatureDeclaration);
|
||||
case utils_1.AST_NODE_TYPES.TSAbstractKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSAnyKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSArrayType:
|
||||
case utils_1.AST_NODE_TYPES.TSAsyncKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSBigIntKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSBooleanKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSDeclareKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSExportKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSIntrinsicKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSLiteralType:
|
||||
case utils_1.AST_NODE_TYPES.TSMappedType:
|
||||
case utils_1.AST_NODE_TYPES.TSNamedTupleMember:
|
||||
case utils_1.AST_NODE_TYPES.TSNeverKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSNullKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSNumberKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSObjectKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSOptionalType:
|
||||
case utils_1.AST_NODE_TYPES.TSPrivateKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSProtectedKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSPublicKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSReadonlyKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSRestType:
|
||||
case utils_1.AST_NODE_TYPES.TSStaticKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSStringKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSSymbolKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSTemplateLiteralType:
|
||||
case utils_1.AST_NODE_TYPES.TSTupleType:
|
||||
case utils_1.AST_NODE_TYPES.TSTypePredicate:
|
||||
case utils_1.AST_NODE_TYPES.TSUndefinedKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSUnknownKeyword:
|
||||
case utils_1.AST_NODE_TYPES.TSVoidKeyword:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function checkTestConditional(node) {
|
||||
if (node.test) {
|
||||
checkConditional(node.test, true);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This function analyzes the type of a node and checks if it is a Promise in a boolean conditional.
|
||||
* It uses recursion when checking nested logical operators.
|
||||
* @param node The AST node to check.
|
||||
* @param isTestExpr Whether the node is a descendant of a test expression.
|
||||
*/
|
||||
function checkConditional(node, isTestExpr = false) {
|
||||
// prevent checking the same node multiple times
|
||||
if (checkedNodes.has(node)) {
|
||||
return;
|
||||
}
|
||||
checkedNodes.add(node);
|
||||
if (node.type === utils_1.AST_NODE_TYPES.LogicalExpression) {
|
||||
// ignore the left operand for nullish coalescing expressions not in a context of a test expression
|
||||
if (node.operator !== '??' || isTestExpr) {
|
||||
checkConditional(node.left, isTestExpr);
|
||||
}
|
||||
// we ignore the right operand when not in a context of a test expression
|
||||
if (isTestExpr) {
|
||||
checkConditional(node.right, isTestExpr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
|
||||
if (isAlwaysThenable(checker, tsNode)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'conditional',
|
||||
});
|
||||
}
|
||||
}
|
||||
function checkArrayPredicates(node) {
|
||||
const parent = node.parent;
|
||||
if (parent.type === utils_1.AST_NODE_TYPES.CallExpression) {
|
||||
const callback = parent.arguments.at(0);
|
||||
if (callback &&
|
||||
(0, util_1.isArrayMethodCallWithPredicate)(context, services, parent)) {
|
||||
const type = services.esTreeNodeToTSNodeMap.get(callback);
|
||||
if (returnsThenable(checker, type)) {
|
||||
context.report({
|
||||
node: callback,
|
||||
messageId: 'predicate',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function checkArguments(node) {
|
||||
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
|
||||
const voidArgs = voidFunctionArguments(checker, tsNode);
|
||||
if (voidArgs.size === 0) {
|
||||
return;
|
||||
}
|
||||
for (const [index, argument] of node.arguments.entries()) {
|
||||
if (!voidArgs.has(index)) {
|
||||
continue;
|
||||
}
|
||||
const tsNode = services.esTreeNodeToTSNodeMap.get(argument);
|
||||
if (returnsThenable(checker, tsNode)) {
|
||||
context.report({
|
||||
node: argument,
|
||||
messageId: 'voidReturnArgument',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
function checkAssignment(node) {
|
||||
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
|
||||
const varType = services.getTypeAtLocation(node.left);
|
||||
if (!isVoidReturningFunctionType(checker, tsNode.left, varType)) {
|
||||
return;
|
||||
}
|
||||
if (returnsThenable(checker, tsNode.right)) {
|
||||
context.report({
|
||||
node: node.right,
|
||||
messageId: 'voidReturnVariable',
|
||||
});
|
||||
}
|
||||
}
|
||||
function checkVariableDeclaration(node) {
|
||||
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
|
||||
if (tsNode.initializer === undefined ||
|
||||
node.init == null ||
|
||||
node.id.typeAnnotation == null) {
|
||||
return;
|
||||
}
|
||||
// syntactically ignore some known-good cases to avoid touching type info
|
||||
if (!isPossiblyFunctionType(node.id.typeAnnotation)) {
|
||||
return;
|
||||
}
|
||||
const varType = services.getTypeAtLocation(node.id);
|
||||
if (!isVoidReturningFunctionType(checker, tsNode.initializer, varType)) {
|
||||
return;
|
||||
}
|
||||
if (returnsThenable(checker, tsNode.initializer)) {
|
||||
context.report({
|
||||
node: node.init,
|
||||
messageId: 'voidReturnVariable',
|
||||
});
|
||||
}
|
||||
}
|
||||
function checkProperty(node) {
|
||||
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
|
||||
if (ts.isPropertyAssignment(tsNode)) {
|
||||
const contextualType = checker.getContextualType(tsNode.initializer);
|
||||
if (contextualType !== undefined &&
|
||||
isVoidReturningFunctionType(checker, tsNode.initializer, contextualType) &&
|
||||
returnsThenable(checker, tsNode.initializer)) {
|
||||
if ((0, util_1.isFunction)(node.value)) {
|
||||
const functionNode = node.value;
|
||||
if (functionNode.returnType) {
|
||||
context.report({
|
||||
node: functionNode.returnType.typeAnnotation,
|
||||
messageId: 'voidReturnProperty',
|
||||
});
|
||||
}
|
||||
else {
|
||||
context.report({
|
||||
loc: (0, util_1.getFunctionHeadLoc)(functionNode, context.sourceCode),
|
||||
messageId: 'voidReturnProperty',
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
context.report({
|
||||
node: node.value,
|
||||
messageId: 'voidReturnProperty',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ts.isShorthandPropertyAssignment(tsNode)) {
|
||||
const contextualType = checker.getContextualType(tsNode.name);
|
||||
if (contextualType !== undefined &&
|
||||
isVoidReturningFunctionType(checker, tsNode.name, contextualType) &&
|
||||
returnsThenable(checker, tsNode.name)) {
|
||||
context.report({
|
||||
node: node.value,
|
||||
messageId: 'voidReturnProperty',
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (ts.isMethodDeclaration(tsNode)) {
|
||||
if (ts.isComputedPropertyName(tsNode.name)) {
|
||||
return;
|
||||
}
|
||||
const obj = tsNode.parent;
|
||||
// Below condition isn't satisfied unless something goes wrong,
|
||||
// but is needed for type checking.
|
||||
// 'node' does not include class method declaration so 'obj' is
|
||||
// always an object literal expression, but after converting 'node'
|
||||
// to TypeScript AST, its type includes MethodDeclaration which
|
||||
// does include the case of class method declaration.
|
||||
if (!ts.isObjectLiteralExpression(obj)) {
|
||||
return;
|
||||
}
|
||||
if (!returnsThenable(checker, tsNode)) {
|
||||
return;
|
||||
}
|
||||
const objType = checker.getContextualType(obj);
|
||||
if (objType === undefined) {
|
||||
return;
|
||||
}
|
||||
const propertySymbol = checker.getPropertyOfType(objType, tsNode.name.text);
|
||||
if (propertySymbol === undefined) {
|
||||
return;
|
||||
}
|
||||
const contextualType = checker.getTypeOfSymbolAtLocation(propertySymbol, tsNode.name);
|
||||
if (isVoidReturningFunctionType(checker, tsNode.name, contextualType)) {
|
||||
const functionNode = node.value;
|
||||
if (functionNode.returnType) {
|
||||
context.report({
|
||||
node: functionNode.returnType.typeAnnotation,
|
||||
messageId: 'voidReturnProperty',
|
||||
});
|
||||
}
|
||||
else {
|
||||
context.report({
|
||||
loc: (0, util_1.getFunctionHeadLoc)(functionNode, context.sourceCode),
|
||||
messageId: 'voidReturnProperty',
|
||||
});
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
function checkReturnStatement(node) {
|
||||
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
|
||||
if (tsNode.expression === undefined || node.argument == null) {
|
||||
return;
|
||||
}
|
||||
// syntactically ignore some known-good cases to avoid touching type info
|
||||
const functionNode = (() => {
|
||||
let current = node.parent;
|
||||
while (current && !(0, util_1.isFunction)(current)) {
|
||||
current = current.parent;
|
||||
}
|
||||
return (0, util_1.nullThrows)(current, util_1.NullThrowsReasons.MissingParent);
|
||||
})();
|
||||
if (functionNode.returnType &&
|
||||
!isPossiblyFunctionType(functionNode.returnType)) {
|
||||
return;
|
||||
}
|
||||
const contextualType = checker.getContextualType(tsNode.expression);
|
||||
if (contextualType !== undefined &&
|
||||
isVoidReturningFunctionType(checker, tsNode.expression, contextualType) &&
|
||||
returnsThenable(checker, tsNode.expression)) {
|
||||
context.report({
|
||||
node: node.argument,
|
||||
messageId: 'voidReturnReturnValue',
|
||||
});
|
||||
}
|
||||
}
|
||||
function checkClassLikeOrInterfaceNode(node) {
|
||||
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
|
||||
const heritageTypes = getHeritageTypes(checker, tsNode);
|
||||
if (!heritageTypes?.length) {
|
||||
return;
|
||||
}
|
||||
for (const nodeMember of tsNode.members) {
|
||||
const memberName = nodeMember.name?.getText();
|
||||
if (memberName === undefined) {
|
||||
// Call/construct/index signatures don't have names. TS allows call signatures to mismatch,
|
||||
// and construct signatures can't be async.
|
||||
// TODO - Once we're able to use `checker.isTypeAssignableTo` (v8), we can check an index
|
||||
// signature here against its compatible index signatures in `heritageTypes`
|
||||
continue;
|
||||
}
|
||||
if (!returnsThenable(checker, nodeMember)) {
|
||||
continue;
|
||||
}
|
||||
const node = services.tsNodeToESTreeNodeMap.get(nodeMember);
|
||||
if (isStaticMember(node)) {
|
||||
continue;
|
||||
}
|
||||
for (const heritageType of heritageTypes) {
|
||||
checkHeritageTypeForMemberReturningVoid(nodeMember, heritageType, memberName);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Checks `heritageType` for a member named `memberName` that returns void; reports the
|
||||
* 'voidReturnInheritedMethod' message if found.
|
||||
* @param nodeMember Node member that returns a Promise
|
||||
* @param heritageType Heritage type to check against
|
||||
* @param memberName Name of the member to check for
|
||||
*/
|
||||
function checkHeritageTypeForMemberReturningVoid(nodeMember, heritageType, memberName) {
|
||||
const heritageMember = getMemberIfExists(heritageType, memberName);
|
||||
if (heritageMember === undefined) {
|
||||
return;
|
||||
}
|
||||
const memberType = checker.getTypeOfSymbolAtLocation(heritageMember, nodeMember);
|
||||
if (!isVoidReturningFunctionType(checker, nodeMember, memberType)) {
|
||||
return;
|
||||
}
|
||||
context.report({
|
||||
node: services.tsNodeToESTreeNodeMap.get(nodeMember),
|
||||
messageId: 'voidReturnInheritedMethod',
|
||||
data: { heritageTypeName: checker.typeToString(heritageType) },
|
||||
});
|
||||
}
|
||||
function checkJSXAttribute(node) {
|
||||
if (node.value == null ||
|
||||
node.value.type !== utils_1.AST_NODE_TYPES.JSXExpressionContainer) {
|
||||
return;
|
||||
}
|
||||
const expressionContainer = services.esTreeNodeToTSNodeMap.get(node.value);
|
||||
const expression = services.esTreeNodeToTSNodeMap.get(node.value.expression);
|
||||
const contextualType = checker.getContextualType(expressionContainer);
|
||||
if (contextualType !== undefined &&
|
||||
isVoidReturningFunctionType(checker, expressionContainer, contextualType) &&
|
||||
returnsThenable(checker, expression)) {
|
||||
context.report({
|
||||
node: node.value,
|
||||
messageId: 'voidReturnAttribute',
|
||||
});
|
||||
}
|
||||
}
|
||||
function checkSpread(node) {
|
||||
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
|
||||
if (isSometimesThenable(checker, tsNode.expression)) {
|
||||
context.report({
|
||||
node: node.argument,
|
||||
messageId: 'spread',
|
||||
});
|
||||
}
|
||||
}
|
||||
return {
|
||||
...(checksConditionals ? conditionalChecks : {}),
|
||||
...(checksVoidReturn ? voidReturnChecks : {}),
|
||||
...(checksSpreads ? spreadChecks : {}),
|
||||
};
|
||||
},
|
||||
});
|
||||
function isSometimesThenable(checker, node) {
|
||||
const type = checker.getTypeAtLocation(node);
|
||||
for (const subType of tsutils.unionTypeParts(checker.getApparentType(type))) {
|
||||
if (tsutils.isThenableType(checker, node, subType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Variation on the thenable check which requires all forms of the type (read:
|
||||
// alternates in a union) to be thenable. Otherwise, you might be trying to
|
||||
// check if something is defined or undefined and get caught because one of the
|
||||
// branches is thenable.
|
||||
function isAlwaysThenable(checker, node) {
|
||||
const type = checker.getTypeAtLocation(node);
|
||||
for (const subType of tsutils.unionTypeParts(checker.getApparentType(type))) {
|
||||
const thenProp = subType.getProperty('then');
|
||||
// If one of the alternates has no then property, it is not thenable in all
|
||||
// cases.
|
||||
if (thenProp === undefined) {
|
||||
return false;
|
||||
}
|
||||
// We walk through each variation of the then property. Since we know it
|
||||
// exists at this point, we just need at least one of the alternates to
|
||||
// be of the right form to consider it thenable.
|
||||
const thenType = checker.getTypeOfSymbolAtLocation(thenProp, node);
|
||||
let hasThenableSignature = false;
|
||||
for (const subType of tsutils.unionTypeParts(thenType)) {
|
||||
for (const signature of subType.getCallSignatures()) {
|
||||
if (signature.parameters.length !== 0 &&
|
||||
isFunctionParam(checker, signature.parameters[0], node)) {
|
||||
hasThenableSignature = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// We only need to find one variant of the then property that has a
|
||||
// function signature for it to be thenable.
|
||||
if (hasThenableSignature) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If no flavors of the then property are thenable, we don't consider the
|
||||
// overall type to be thenable
|
||||
if (!hasThenableSignature) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// If all variants are considered thenable (i.e. haven't returned false), we
|
||||
// consider the overall type thenable
|
||||
return true;
|
||||
}
|
||||
function isFunctionParam(checker, param, node) {
|
||||
const type = checker.getApparentType(checker.getTypeOfSymbolAtLocation(param, node));
|
||||
for (const subType of tsutils.unionTypeParts(type)) {
|
||||
if (subType.getCallSignatures().length !== 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function checkThenableOrVoidArgument(checker, node, type, index, thenableReturnIndices, voidReturnIndices) {
|
||||
if (isThenableReturningFunctionType(checker, node.expression, type)) {
|
||||
thenableReturnIndices.add(index);
|
||||
}
|
||||
else if (isVoidReturningFunctionType(checker, node.expression, type) &&
|
||||
// If a certain argument accepts both thenable and void returns,
|
||||
// a promise-returning function is valid
|
||||
!thenableReturnIndices.has(index)) {
|
||||
voidReturnIndices.add(index);
|
||||
}
|
||||
const contextualType = checker.getContextualTypeForArgumentAtIndex(node, index);
|
||||
if (contextualType !== type) {
|
||||
checkThenableOrVoidArgument(checker, node, contextualType, index, thenableReturnIndices, voidReturnIndices);
|
||||
}
|
||||
}
|
||||
// Get the positions of arguments which are void functions (and not also
|
||||
// thenable functions). These are the candidates for the void-return check at
|
||||
// the current call site.
|
||||
// If the function parameters end with a 'rest' parameter, then we consider
|
||||
// the array type parameter (e.g. '...args:Array<SomeType>') when determining
|
||||
// if trailing arguments are candidates.
|
||||
function voidFunctionArguments(checker, node) {
|
||||
// 'new' can be used without any arguments, as in 'let b = new Object;'
|
||||
// In this case, there are no argument positions to check, so return early.
|
||||
if (!node.arguments) {
|
||||
return new Set();
|
||||
}
|
||||
const thenableReturnIndices = new Set();
|
||||
const voidReturnIndices = new Set();
|
||||
const type = checker.getTypeAtLocation(node.expression);
|
||||
// We can't use checker.getResolvedSignature because it prefers an early '() => void' over a later '() => Promise<void>'
|
||||
// See https://github.com/microsoft/TypeScript/issues/48077
|
||||
for (const subType of tsutils.unionTypeParts(type)) {
|
||||
// Standard function calls and `new` have two different types of signatures
|
||||
const signatures = ts.isCallExpression(node)
|
||||
? subType.getCallSignatures()
|
||||
: subType.getConstructSignatures();
|
||||
for (const signature of signatures) {
|
||||
for (const [index, parameter] of signature.parameters.entries()) {
|
||||
const decl = parameter.valueDeclaration;
|
||||
let type = checker.getTypeOfSymbolAtLocation(parameter, node.expression);
|
||||
// If this is a array 'rest' parameter, check all of the argument indices
|
||||
// from the current argument to the end.
|
||||
if (decl && (0, util_1.isRestParameterDeclaration)(decl)) {
|
||||
if (checker.isArrayType(type)) {
|
||||
// Unwrap 'Array<MaybeVoidFunction>' to 'MaybeVoidFunction',
|
||||
// so that we'll handle it in the same way as a non-rest
|
||||
// 'param: MaybeVoidFunction'
|
||||
type = checker.getTypeArguments(type)[0];
|
||||
for (let i = index; i < node.arguments.length; i++) {
|
||||
checkThenableOrVoidArgument(checker, node, type, i, thenableReturnIndices, voidReturnIndices);
|
||||
}
|
||||
}
|
||||
else if (checker.isTupleType(type)) {
|
||||
// Check each type in the tuple - for example, [boolean, () => void] would
|
||||
// add the index of the second tuple parameter to 'voidReturnIndices'
|
||||
const typeArgs = checker.getTypeArguments(type);
|
||||
for (let i = index; i < node.arguments.length && i - index < typeArgs.length; i++) {
|
||||
checkThenableOrVoidArgument(checker, node, typeArgs[i - index], i, thenableReturnIndices, voidReturnIndices);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
checkThenableOrVoidArgument(checker, node, type, index, thenableReturnIndices, voidReturnIndices);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const index of thenableReturnIndices) {
|
||||
voidReturnIndices.delete(index);
|
||||
}
|
||||
return voidReturnIndices;
|
||||
}
|
||||
/**
|
||||
* @returns Whether any call signature of the type has a thenable return type.
|
||||
*/
|
||||
function anySignatureIsThenableType(checker, node, type) {
|
||||
for (const signature of type.getCallSignatures()) {
|
||||
const returnType = signature.getReturnType();
|
||||
if (tsutils.isThenableType(checker, node, returnType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* @returns Whether type is a thenable-returning function.
|
||||
*/
|
||||
function isThenableReturningFunctionType(checker, node, type) {
|
||||
for (const subType of tsutils.unionTypeParts(type)) {
|
||||
if (anySignatureIsThenableType(checker, node, subType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* @returns Whether type is a void-returning function.
|
||||
*/
|
||||
function isVoidReturningFunctionType(checker, node, type) {
|
||||
let hadVoidReturn = false;
|
||||
for (const subType of tsutils.unionTypeParts(type)) {
|
||||
for (const signature of subType.getCallSignatures()) {
|
||||
const returnType = signature.getReturnType();
|
||||
// If a certain positional argument accepts both thenable and void returns,
|
||||
// a promise-returning function is valid
|
||||
if (tsutils.isThenableType(checker, node, returnType)) {
|
||||
return false;
|
||||
}
|
||||
hadVoidReturn ||= tsutils.isTypeFlagSet(returnType, ts.TypeFlags.Void);
|
||||
}
|
||||
}
|
||||
return hadVoidReturn;
|
||||
}
|
||||
/**
|
||||
* @returns Whether expression is a function that returns a thenable.
|
||||
*/
|
||||
function returnsThenable(checker, node) {
|
||||
const type = checker.getApparentType(checker.getTypeAtLocation(node));
|
||||
return tsutils
|
||||
.unionTypeParts(type)
|
||||
.some(t => anySignatureIsThenableType(checker, node, t));
|
||||
}
|
||||
function getHeritageTypes(checker, tsNode) {
|
||||
return tsNode.heritageClauses
|
||||
?.flatMap(clause => clause.types)
|
||||
.map(typeExpression => checker.getTypeAtLocation(typeExpression));
|
||||
}
|
||||
/**
|
||||
* @returns The member with the given name in `type`, if it exists.
|
||||
*/
|
||||
function getMemberIfExists(type, memberName) {
|
||||
const escapedMemberName = ts.escapeLeadingUnderscores(memberName);
|
||||
const symbolMemberMatch = type.getSymbol()?.members?.get(escapedMemberName);
|
||||
return (symbolMemberMatch ?? tsutils.getPropertyOfType(type, escapedMemberName));
|
||||
}
|
||||
function isStaticMember(node) {
|
||||
return ((node.type === utils_1.AST_NODE_TYPES.MethodDefinition ||
|
||||
node.type === utils_1.AST_NODE_TYPES.PropertyDefinition) &&
|
||||
node.static);
|
||||
}
|
||||
//# sourceMappingURL=no-misused-promises.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+634
@@ -0,0 +1,634 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
const tsutils = __importStar(require("ts-api-utils"));
|
||||
const ts = __importStar(require("typescript"));
|
||||
const util_1 = require("../util");
|
||||
const assertionFunctionUtils_1 = require("../util/assertionFunctionUtils");
|
||||
// Truthiness utilities
|
||||
// #region
|
||||
const valueIsPseudoBigInt = (value) => {
|
||||
return typeof value === 'object';
|
||||
};
|
||||
const getValueOfLiteralType = (type) => {
|
||||
if (valueIsPseudoBigInt(type.value)) {
|
||||
return pseudoBigIntToBigInt(type.value);
|
||||
}
|
||||
return type.value;
|
||||
};
|
||||
const isFalsyBigInt = (type) => {
|
||||
return (tsutils.isLiteralType(type) &&
|
||||
valueIsPseudoBigInt(type.value) &&
|
||||
!getValueOfLiteralType(type));
|
||||
};
|
||||
const isTruthyLiteral = (type) => tsutils.isTrueLiteralType(type) ||
|
||||
(type.isLiteral() && !!getValueOfLiteralType(type));
|
||||
const isPossiblyFalsy = (type) => tsutils
|
||||
.unionTypeParts(type)
|
||||
// Intersections like `string & {}` can also be possibly falsy,
|
||||
// requiring us to look into the intersection.
|
||||
.flatMap(type => tsutils.intersectionTypeParts(type))
|
||||
// PossiblyFalsy flag includes literal values, so exclude ones that
|
||||
// are definitely truthy
|
||||
.filter(t => !isTruthyLiteral(t))
|
||||
.some(type => (0, util_1.isTypeFlagSet)(type, ts.TypeFlags.PossiblyFalsy));
|
||||
const isPossiblyTruthy = (type) => tsutils
|
||||
.unionTypeParts(type)
|
||||
.map(type => tsutils.intersectionTypeParts(type))
|
||||
.some(intersectionParts =>
|
||||
// It is possible to define intersections that are always falsy,
|
||||
// like `"" & { __brand: string }`.
|
||||
intersectionParts.every(type => !tsutils.isFalsyType(type) &&
|
||||
// below is a workaround for ts-api-utils bug
|
||||
// see https://github.com/JoshuaKGoldberg/ts-api-utils/issues/544
|
||||
!isFalsyBigInt(type)));
|
||||
// Nullish utilities
|
||||
const nullishFlag = ts.TypeFlags.Undefined | ts.TypeFlags.Null;
|
||||
const isNullishType = (type) => (0, util_1.isTypeFlagSet)(type, nullishFlag);
|
||||
const isPossiblyNullish = (type) => tsutils.unionTypeParts(type).some(isNullishType);
|
||||
const isAlwaysNullish = (type) => tsutils.unionTypeParts(type).every(isNullishType);
|
||||
function toStaticValue(type) {
|
||||
// type.isLiteral() only covers numbers/bigints and strings, hence the rest of the branches.
|
||||
if (tsutils.isBooleanLiteralType(type)) {
|
||||
// Using `type.intrinsicName` instead of `type.value` because `type.value`
|
||||
// is `undefined`, contrary to what the type guard tells us.
|
||||
// See https://github.com/JoshuaKGoldberg/ts-api-utils/issues/528
|
||||
return { value: type.intrinsicName === 'true' };
|
||||
}
|
||||
if (type.flags === ts.TypeFlags.Undefined) {
|
||||
return { value: undefined };
|
||||
}
|
||||
if (type.flags === ts.TypeFlags.Null) {
|
||||
return { value: null };
|
||||
}
|
||||
if (type.isLiteral()) {
|
||||
return { value: getValueOfLiteralType(type) };
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
function pseudoBigIntToBigInt(value) {
|
||||
return BigInt((value.negative ? '-' : '') + value.base10Value);
|
||||
}
|
||||
const BOOL_OPERATORS = new Set([
|
||||
'<',
|
||||
'>',
|
||||
'<=',
|
||||
'>=',
|
||||
'==',
|
||||
'===',
|
||||
'!=',
|
||||
'!==',
|
||||
]);
|
||||
function isBoolOperator(operator) {
|
||||
return BOOL_OPERATORS.has(operator);
|
||||
}
|
||||
function booleanComparison(left, operator, right) {
|
||||
switch (operator) {
|
||||
case '!=':
|
||||
// eslint-disable-next-line eqeqeq -- intentionally comparing with loose equality
|
||||
return left != right;
|
||||
case '!==':
|
||||
return left !== right;
|
||||
case '<':
|
||||
// @ts-expect-error: we don't care if the comparison seems unintentional.
|
||||
return left < right;
|
||||
case '<=':
|
||||
// @ts-expect-error: we don't care if the comparison seems unintentional.
|
||||
return left <= right;
|
||||
case '==':
|
||||
// eslint-disable-next-line eqeqeq -- intentionally comparing with loose equality
|
||||
return left == right;
|
||||
case '===':
|
||||
return left === right;
|
||||
case '>':
|
||||
// @ts-expect-error: we don't care if the comparison seems unintentional.
|
||||
return left > right;
|
||||
case '>=':
|
||||
// @ts-expect-error: we don't care if the comparison seems unintentional.
|
||||
return left >= right;
|
||||
}
|
||||
}
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'no-unnecessary-condition',
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'Disallow conditionals where the type is always truthy or always falsy',
|
||||
recommended: 'strict',
|
||||
requiresTypeChecking: true,
|
||||
},
|
||||
fixable: 'code',
|
||||
messages: {
|
||||
alwaysFalsy: 'Unnecessary conditional, value is always falsy.',
|
||||
alwaysFalsyFunc: 'This callback should return a conditional, but return is always falsy.',
|
||||
alwaysNullish: 'Unnecessary conditional, left-hand side of `??` operator is always `null` or `undefined`.',
|
||||
alwaysTruthy: 'Unnecessary conditional, value is always truthy.',
|
||||
alwaysTruthyFunc: 'This callback should return a conditional, but return is always truthy.',
|
||||
literalBooleanExpression: 'Unnecessary conditional, comparison is always {{trueOrFalse}}. Both sides of the comparison always have a literal type.',
|
||||
never: 'Unnecessary conditional, value is `never`.',
|
||||
neverNullish: 'Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined.',
|
||||
neverOptionalChain: 'Unnecessary optional chain on a non-nullish value.',
|
||||
noOverlapBooleanExpression: 'Unnecessary conditional, the types have no overlap.',
|
||||
noStrictNullCheck: 'This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.',
|
||||
typeGuardAlreadyIsType: 'Unnecessary conditional, expression already has the type being checked by the {{typeGuardOrAssertionFunction}}.',
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
allowConstantLoopConditions: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to ignore constant loop conditions, such as `while (true)`.',
|
||||
},
|
||||
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to not error when running with a tsconfig that has strictNullChecks turned.',
|
||||
},
|
||||
checkTypePredicates: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to check the asserted argument of a type predicate function for unnecessary conditions',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultOptions: [
|
||||
{
|
||||
allowConstantLoopConditions: false,
|
||||
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: false,
|
||||
checkTypePredicates: false,
|
||||
},
|
||||
],
|
||||
create(context, [{ allowConstantLoopConditions, allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing, checkTypePredicates, },]) {
|
||||
const services = (0, util_1.getParserServices)(context);
|
||||
const checker = services.program.getTypeChecker();
|
||||
const compilerOptions = services.program.getCompilerOptions();
|
||||
const isStrictNullChecks = tsutils.isStrictCompilerOptionEnabled(compilerOptions, 'strictNullChecks');
|
||||
if (!isStrictNullChecks &&
|
||||
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing !== true) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: { column: 0, line: 0 },
|
||||
end: { column: 0, line: 0 },
|
||||
},
|
||||
messageId: 'noStrictNullCheck',
|
||||
});
|
||||
}
|
||||
function nodeIsArrayType(node) {
|
||||
const nodeType = (0, util_1.getConstrainedTypeAtLocation)(services, node);
|
||||
return tsutils
|
||||
.unionTypeParts(nodeType)
|
||||
.some(part => checker.isArrayType(part));
|
||||
}
|
||||
function nodeIsTupleType(node) {
|
||||
const nodeType = (0, util_1.getConstrainedTypeAtLocation)(services, node);
|
||||
return tsutils
|
||||
.unionTypeParts(nodeType)
|
||||
.some(part => checker.isTupleType(part));
|
||||
}
|
||||
function isArrayIndexExpression(node) {
|
||||
return (
|
||||
// Is an index signature
|
||||
node.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
||||
node.computed &&
|
||||
// ...into an array type
|
||||
(nodeIsArrayType(node.object) ||
|
||||
// ... or a tuple type
|
||||
(nodeIsTupleType(node.object) &&
|
||||
// Exception: literal index into a tuple - will have a sound type
|
||||
node.property.type !== utils_1.AST_NODE_TYPES.Literal)));
|
||||
}
|
||||
function isNullableMemberExpression(node) {
|
||||
const objectType = services.getTypeAtLocation(node.object);
|
||||
if (node.computed) {
|
||||
const propertyType = services.getTypeAtLocation(node.property);
|
||||
return isNullablePropertyType(objectType, propertyType);
|
||||
}
|
||||
const property = node.property;
|
||||
// Get the actual property name, to account for private properties (this.#prop).
|
||||
const propertyName = context.sourceCode.getText(property);
|
||||
const propertyType = objectType
|
||||
.getProperties()
|
||||
.find(prop => prop.name === propertyName);
|
||||
if (propertyType &&
|
||||
tsutils.isSymbolFlagSet(propertyType, ts.SymbolFlags.Optional)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Checks if a conditional node is necessary:
|
||||
* if the type of the node is always true or always false, it's not necessary.
|
||||
*/
|
||||
function checkNode(expression, isUnaryNotArgument = false, node = expression) {
|
||||
// Check if the node is Unary Negation expression and handle it
|
||||
if (expression.type === utils_1.AST_NODE_TYPES.UnaryExpression &&
|
||||
expression.operator === '!') {
|
||||
return checkNode(expression.argument, !isUnaryNotArgument, node);
|
||||
}
|
||||
// Since typescript array index signature types don't represent the
|
||||
// possibility of out-of-bounds access, if we're indexing into an array
|
||||
// just skip the check, to avoid false positives
|
||||
if (isArrayIndexExpression(expression)) {
|
||||
return;
|
||||
}
|
||||
// When checking logical expressions, only check the right side
|
||||
// as the left side has been checked by checkLogicalExpressionForUnnecessaryConditionals
|
||||
//
|
||||
// Unless the node is nullish coalescing, as it's common to use patterns like `nullBool ?? true` to to strict
|
||||
// boolean checks if we inspect the right here, it'll usually be a constant condition on purpose.
|
||||
// In this case it's better to inspect the type of the expression as a whole.
|
||||
if (expression.type === utils_1.AST_NODE_TYPES.LogicalExpression &&
|
||||
expression.operator !== '??') {
|
||||
return checkNode(expression.right);
|
||||
}
|
||||
const type = (0, util_1.getConstrainedTypeAtLocation)(services, expression);
|
||||
// Conditional is always necessary if it involves:
|
||||
// `any` or `unknown` or a naked type variable
|
||||
if (tsutils
|
||||
.unionTypeParts(type)
|
||||
.some(part => (0, util_1.isTypeAnyType)(part) ||
|
||||
(0, util_1.isTypeUnknownType)(part) ||
|
||||
(0, util_1.isTypeFlagSet)(part, ts.TypeFlags.TypeVariable))) {
|
||||
return;
|
||||
}
|
||||
let messageId = null;
|
||||
if ((0, util_1.isTypeFlagSet)(type, ts.TypeFlags.Never)) {
|
||||
messageId = 'never';
|
||||
}
|
||||
else if (!isPossiblyTruthy(type)) {
|
||||
messageId = !isUnaryNotArgument ? 'alwaysFalsy' : 'alwaysTruthy';
|
||||
}
|
||||
else if (!isPossiblyFalsy(type)) {
|
||||
messageId = !isUnaryNotArgument ? 'alwaysTruthy' : 'alwaysFalsy';
|
||||
}
|
||||
if (messageId) {
|
||||
context.report({ node, messageId });
|
||||
}
|
||||
}
|
||||
function checkNodeForNullish(node) {
|
||||
const type = (0, util_1.getConstrainedTypeAtLocation)(services, node);
|
||||
// Conditional is always necessary if it involves `any`, `unknown` or a naked type parameter
|
||||
if ((0, util_1.isTypeFlagSet)(type, ts.TypeFlags.Any |
|
||||
ts.TypeFlags.Unknown |
|
||||
ts.TypeFlags.TypeParameter |
|
||||
ts.TypeFlags.TypeVariable)) {
|
||||
return;
|
||||
}
|
||||
let messageId = null;
|
||||
if ((0, util_1.isTypeFlagSet)(type, ts.TypeFlags.Never)) {
|
||||
messageId = 'never';
|
||||
}
|
||||
else if (!isPossiblyNullish(type) &&
|
||||
!(node.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
||||
isNullableMemberExpression(node))) {
|
||||
// Since typescript array index signature types don't represent the
|
||||
// possibility of out-of-bounds access, if we're indexing into an array
|
||||
// just skip the check, to avoid false positives
|
||||
if (!isArrayIndexExpression(node) &&
|
||||
!(node.type === utils_1.AST_NODE_TYPES.ChainExpression &&
|
||||
node.expression.type !== utils_1.AST_NODE_TYPES.TSNonNullExpression &&
|
||||
optionChainContainsOptionArrayIndex(node.expression))) {
|
||||
messageId = 'neverNullish';
|
||||
}
|
||||
}
|
||||
else if (isAlwaysNullish(type)) {
|
||||
messageId = 'alwaysNullish';
|
||||
}
|
||||
if (messageId) {
|
||||
context.report({ node, messageId });
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Checks that a binary expression is necessarily conditional, reports otherwise.
|
||||
* If both sides of the binary expression are literal values, it's not a necessary condition.
|
||||
*
|
||||
* NOTE: It's also unnecessary if the types that don't overlap at all
|
||||
* but that case is handled by the Typescript compiler itself.
|
||||
* Known exceptions:
|
||||
* - https://github.com/microsoft/TypeScript/issues/32627
|
||||
* - https://github.com/microsoft/TypeScript/issues/37160 (handled)
|
||||
*/
|
||||
function checkIfBoolExpressionIsNecessaryConditional(node, left, right, operator) {
|
||||
const leftType = (0, util_1.getConstrainedTypeAtLocation)(services, left);
|
||||
const rightType = (0, util_1.getConstrainedTypeAtLocation)(services, right);
|
||||
const leftStaticValue = toStaticValue(leftType);
|
||||
const rightStaticValue = toStaticValue(rightType);
|
||||
if (leftStaticValue != null && rightStaticValue != null) {
|
||||
const conditionIsTrue = booleanComparison(leftStaticValue.value, operator, rightStaticValue.value);
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'literalBooleanExpression',
|
||||
data: {
|
||||
trueOrFalse: conditionIsTrue ? 'true' : 'false',
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Workaround for https://github.com/microsoft/TypeScript/issues/37160
|
||||
if (isStrictNullChecks) {
|
||||
const UNDEFINED = ts.TypeFlags.Undefined;
|
||||
const NULL = ts.TypeFlags.Null;
|
||||
const VOID = ts.TypeFlags.Void;
|
||||
const isComparable = (type, flag) => {
|
||||
// Allow comparison to `any`, `unknown` or a naked type parameter.
|
||||
flag |=
|
||||
ts.TypeFlags.Any |
|
||||
ts.TypeFlags.Unknown |
|
||||
ts.TypeFlags.TypeParameter |
|
||||
ts.TypeFlags.TypeVariable;
|
||||
// Allow loose comparison to nullish values.
|
||||
if (operator === '==' || operator === '!=') {
|
||||
flag |= NULL | UNDEFINED | VOID;
|
||||
}
|
||||
return (0, util_1.isTypeFlagSet)(type, flag);
|
||||
};
|
||||
if ((leftType.flags === UNDEFINED &&
|
||||
!isComparable(rightType, UNDEFINED | VOID)) ||
|
||||
(rightType.flags === UNDEFINED &&
|
||||
!isComparable(leftType, UNDEFINED | VOID)) ||
|
||||
(leftType.flags === NULL && !isComparable(rightType, NULL)) ||
|
||||
(rightType.flags === NULL && !isComparable(leftType, NULL))) {
|
||||
context.report({ node, messageId: 'noOverlapBooleanExpression' });
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Checks that a logical expression contains a boolean, reports otherwise.
|
||||
*/
|
||||
function checkLogicalExpressionForUnnecessaryConditionals(node) {
|
||||
if (node.operator === '??') {
|
||||
checkNodeForNullish(node.left);
|
||||
return;
|
||||
}
|
||||
// Only checks the left side, since the right side might not be "conditional" at all.
|
||||
// The right side will be checked if the LogicalExpression is used in a conditional context
|
||||
checkNode(node.left);
|
||||
}
|
||||
/**
|
||||
* Checks that a testable expression of a loop is necessarily conditional, reports otherwise.
|
||||
*/
|
||||
function checkIfLoopIsNecessaryConditional(node) {
|
||||
if (node.test == null) {
|
||||
// e.g. `for(;;)`
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Allow:
|
||||
* while (true) {}
|
||||
* for (;true;) {}
|
||||
* do {} while (true)
|
||||
*/
|
||||
if (allowConstantLoopConditions &&
|
||||
tsutils.isTrueLiteralType((0, util_1.getConstrainedTypeAtLocation)(services, node.test))) {
|
||||
return;
|
||||
}
|
||||
checkNode(node.test);
|
||||
}
|
||||
function checkCallExpression(node) {
|
||||
if (checkTypePredicates) {
|
||||
const truthinessAssertedArgument = (0, assertionFunctionUtils_1.findTruthinessAssertedArgument)(services, node);
|
||||
if (truthinessAssertedArgument != null) {
|
||||
checkNode(truthinessAssertedArgument);
|
||||
}
|
||||
const typeGuardAssertedArgument = (0, assertionFunctionUtils_1.findTypeGuardAssertedArgument)(services, node);
|
||||
if (typeGuardAssertedArgument != null) {
|
||||
const typeOfArgument = (0, util_1.getConstrainedTypeAtLocation)(services, typeGuardAssertedArgument.argument);
|
||||
if (typeOfArgument === typeGuardAssertedArgument.type) {
|
||||
context.report({
|
||||
node: typeGuardAssertedArgument.argument,
|
||||
messageId: 'typeGuardAlreadyIsType',
|
||||
data: {
|
||||
typeGuardOrAssertionFunction: typeGuardAssertedArgument.asserts
|
||||
? 'assertion function'
|
||||
: 'type guard',
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
// If this is something like arr.filter(x => /*condition*/), check `condition`
|
||||
if ((0, util_1.isArrayMethodCallWithPredicate)(context, services, node) &&
|
||||
node.arguments.length) {
|
||||
const callback = node.arguments[0];
|
||||
// Inline defined functions
|
||||
if (callback.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
|
||||
callback.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
|
||||
// Two special cases, where we can directly check the node that's returned:
|
||||
// () => something
|
||||
if (callback.body.type !== utils_1.AST_NODE_TYPES.BlockStatement) {
|
||||
return checkNode(callback.body);
|
||||
}
|
||||
// () => { return something; }
|
||||
const callbackBody = callback.body.body;
|
||||
if (callbackBody.length === 1 &&
|
||||
callbackBody[0].type === utils_1.AST_NODE_TYPES.ReturnStatement &&
|
||||
callbackBody[0].argument) {
|
||||
return checkNode(callbackBody[0].argument);
|
||||
}
|
||||
// Potential enhancement: could use code-path analysis to check
|
||||
// any function with a single return statement
|
||||
// (Value to complexity ratio is dubious however)
|
||||
}
|
||||
// Otherwise just do type analysis on the function as a whole.
|
||||
const returnTypes = tsutils
|
||||
.getCallSignaturesOfType((0, util_1.getConstrainedTypeAtLocation)(services, callback))
|
||||
.map(sig => sig.getReturnType());
|
||||
/* istanbul ignore if */ if (returnTypes.length === 0) {
|
||||
// Not a callable function
|
||||
return;
|
||||
}
|
||||
// Predicate is always necessary if it involves `any` or `unknown`
|
||||
if (returnTypes.some(t => (0, util_1.isTypeAnyType)(t) || (0, util_1.isTypeUnknownType)(t))) {
|
||||
return;
|
||||
}
|
||||
if (!returnTypes.some(isPossiblyFalsy)) {
|
||||
return context.report({
|
||||
node: callback,
|
||||
messageId: 'alwaysTruthyFunc',
|
||||
});
|
||||
}
|
||||
if (!returnTypes.some(isPossiblyTruthy)) {
|
||||
return context.report({
|
||||
node: callback,
|
||||
messageId: 'alwaysFalsyFunc',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
// Recursively searches an optional chain for an array index expression
|
||||
// Has to search the entire chain, because an array index will "infect" the rest of the types
|
||||
// Example:
|
||||
// ```
|
||||
// [{x: {y: "z"} }][n] // type is {x: {y: "z"}}
|
||||
// ?.x // type is {y: "z"}
|
||||
// ?.y // This access is considered "unnecessary" according to the types
|
||||
// ```
|
||||
function optionChainContainsOptionArrayIndex(node) {
|
||||
const lhsNode = node.type === utils_1.AST_NODE_TYPES.CallExpression ? node.callee : node.object;
|
||||
if (node.optional && isArrayIndexExpression(lhsNode)) {
|
||||
return true;
|
||||
}
|
||||
if (lhsNode.type === utils_1.AST_NODE_TYPES.MemberExpression ||
|
||||
lhsNode.type === utils_1.AST_NODE_TYPES.CallExpression) {
|
||||
return optionChainContainsOptionArrayIndex(lhsNode);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function isNullablePropertyType(objType, propertyType) {
|
||||
if (propertyType.isUnion()) {
|
||||
return propertyType.types.some(type => isNullablePropertyType(objType, type));
|
||||
}
|
||||
if (propertyType.isNumberLiteral() || propertyType.isStringLiteral()) {
|
||||
const propType = (0, util_1.getTypeOfPropertyOfName)(checker, objType, propertyType.value.toString());
|
||||
if (propType) {
|
||||
return (0, util_1.isNullableType)(propType);
|
||||
}
|
||||
}
|
||||
const typeName = (0, util_1.getTypeName)(checker, propertyType);
|
||||
return checker
|
||||
.getIndexInfosOfType(objType)
|
||||
.some(info => (0, util_1.getTypeName)(checker, info.keyType) === typeName);
|
||||
}
|
||||
// Checks whether a member expression is nullable or not regardless of it's previous node.
|
||||
// Example:
|
||||
// ```
|
||||
// // 'bar' is nullable if 'foo' is null.
|
||||
// // but this function checks regardless of 'foo' type, so returns 'true'.
|
||||
// declare const foo: { bar : { baz: string } } | null
|
||||
// foo?.bar;
|
||||
// ```
|
||||
function isMemberExpressionNullableOriginFromObject(node) {
|
||||
const prevType = (0, util_1.getConstrainedTypeAtLocation)(services, node.object);
|
||||
const property = node.property;
|
||||
if (prevType.isUnion() && (0, util_1.isIdentifier)(property)) {
|
||||
const isOwnNullable = prevType.types.some(type => {
|
||||
if (node.computed) {
|
||||
const propertyType = (0, util_1.getConstrainedTypeAtLocation)(services, node.property);
|
||||
return isNullablePropertyType(type, propertyType);
|
||||
}
|
||||
const propType = (0, util_1.getTypeOfPropertyOfName)(checker, type, property.name);
|
||||
if (propType) {
|
||||
return (0, util_1.isNullableType)(propType);
|
||||
}
|
||||
return !!checker.getIndexInfoOfType(type, ts.IndexKind.String);
|
||||
});
|
||||
return !isOwnNullable && (0, util_1.isNullableType)(prevType);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function isCallExpressionNullableOriginFromCallee(node) {
|
||||
const prevType = (0, util_1.getConstrainedTypeAtLocation)(services, node.callee);
|
||||
if (prevType.isUnion()) {
|
||||
const isOwnNullable = prevType.types.some(type => {
|
||||
const signatures = type.getCallSignatures();
|
||||
return signatures.some(sig => (0, util_1.isNullableType)(sig.getReturnType()));
|
||||
});
|
||||
return !isOwnNullable && (0, util_1.isNullableType)(prevType);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function isOptionableExpression(node) {
|
||||
const type = (0, util_1.getConstrainedTypeAtLocation)(services, node);
|
||||
const isOwnNullable = node.type === utils_1.AST_NODE_TYPES.MemberExpression
|
||||
? !isMemberExpressionNullableOriginFromObject(node)
|
||||
: node.type === utils_1.AST_NODE_TYPES.CallExpression
|
||||
? !isCallExpressionNullableOriginFromCallee(node)
|
||||
: true;
|
||||
return ((0, util_1.isTypeFlagSet)(type, ts.TypeFlags.Any | ts.TypeFlags.Unknown) ||
|
||||
(isOwnNullable && (0, util_1.isNullableType)(type)));
|
||||
}
|
||||
function checkOptionalChain(node, beforeOperator, fix) {
|
||||
// We only care if this step in the chain is optional. If just descend
|
||||
// from an optional chain, then that's fine.
|
||||
if (!node.optional) {
|
||||
return;
|
||||
}
|
||||
// Since typescript array index signature types don't represent the
|
||||
// possibility of out-of-bounds access, if we're indexing into an array
|
||||
// just skip the check, to avoid false positives
|
||||
if (optionChainContainsOptionArrayIndex(node)) {
|
||||
return;
|
||||
}
|
||||
const nodeToCheck = node.type === utils_1.AST_NODE_TYPES.CallExpression ? node.callee : node.object;
|
||||
if (isOptionableExpression(nodeToCheck)) {
|
||||
return;
|
||||
}
|
||||
const questionDotOperator = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(beforeOperator, token => token.type === utils_1.AST_TOKEN_TYPES.Punctuator && token.value === '?.'), util_1.NullThrowsReasons.MissingToken('operator', node.type));
|
||||
context.report({
|
||||
loc: questionDotOperator.loc,
|
||||
node,
|
||||
messageId: 'neverOptionalChain',
|
||||
fix(fixer) {
|
||||
return fixer.replaceText(questionDotOperator, fix);
|
||||
},
|
||||
});
|
||||
}
|
||||
function checkOptionalMemberExpression(node) {
|
||||
checkOptionalChain(node, node.object, node.computed ? '' : '.');
|
||||
}
|
||||
function checkOptionalCallExpression(node) {
|
||||
checkOptionalChain(node, node.callee, '');
|
||||
}
|
||||
function checkAssignmentExpression(node) {
|
||||
// Similar to checkLogicalExpressionForUnnecessaryConditionals, since
|
||||
// a ||= b is equivalent to a || (a = b)
|
||||
if (['&&=', '||='].includes(node.operator)) {
|
||||
checkNode(node.left);
|
||||
}
|
||||
else if (node.operator === '??=') {
|
||||
checkNodeForNullish(node.left);
|
||||
}
|
||||
}
|
||||
return {
|
||||
AssignmentExpression: checkAssignmentExpression,
|
||||
BinaryExpression(node) {
|
||||
const { operator } = node;
|
||||
if (isBoolOperator(operator)) {
|
||||
checkIfBoolExpressionIsNecessaryConditional(node, node.left, node.right, operator);
|
||||
}
|
||||
},
|
||||
CallExpression: checkCallExpression,
|
||||
'CallExpression[optional = true]': checkOptionalCallExpression,
|
||||
ConditionalExpression: (node) => checkNode(node.test),
|
||||
DoWhileStatement: checkIfLoopIsNecessaryConditional,
|
||||
ForStatement: checkIfLoopIsNecessaryConditional,
|
||||
IfStatement: (node) => checkNode(node.test),
|
||||
LogicalExpression: checkLogicalExpressionForUnnecessaryConditionals,
|
||||
'MemberExpression[optional = true]': checkOptionalMemberExpression,
|
||||
SwitchCase({ parent, test }) {
|
||||
// only check `case ...:`, not `default:`
|
||||
if (test) {
|
||||
checkIfBoolExpressionIsNecessaryConditional(test, parent.discriminant, test, '===');
|
||||
}
|
||||
},
|
||||
WhileStatement: checkIfLoopIsNecessaryConditional,
|
||||
};
|
||||
},
|
||||
});
|
||||
//# sourceMappingURL=no-unnecessary-condition.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
+176
@@ -0,0 +1,176 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tsutils = __importStar(require("ts-api-utils"));
|
||||
const ts = __importStar(require("typescript"));
|
||||
const util_1 = require("../util");
|
||||
const getParentFunctionNode_1 = require("../util/getParentFunctionNode");
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'no-unsafe-return',
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Disallow returning a value with type `any` from a function',
|
||||
recommended: 'recommended',
|
||||
requiresTypeChecking: true,
|
||||
},
|
||||
messages: {
|
||||
unsafeReturn: 'Unsafe return of a value of type {{type}}.',
|
||||
unsafeReturnAssignment: 'Unsafe return of type `{{sender}}` from function with return type `{{receiver}}`.',
|
||||
unsafeReturnThis: [
|
||||
'Unsafe return of a value of type `{{type}}`. `this` is typed as `any`.',
|
||||
'You can try to fix this by turning on the `noImplicitThis` compiler option, or adding a `this` parameter to the function.',
|
||||
].join('\n'),
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
defaultOptions: [],
|
||||
create(context) {
|
||||
const services = (0, util_1.getParserServices)(context);
|
||||
const checker = services.program.getTypeChecker();
|
||||
const compilerOptions = services.program.getCompilerOptions();
|
||||
const isNoImplicitThis = tsutils.isStrictCompilerOptionEnabled(compilerOptions, 'noImplicitThis');
|
||||
function checkReturn(returnNode, reportingNode = returnNode) {
|
||||
const tsNode = services.esTreeNodeToTSNodeMap.get(returnNode);
|
||||
const type = checker.getTypeAtLocation(tsNode);
|
||||
const anyType = (0, util_1.discriminateAnyType)(type, checker, services.program, tsNode);
|
||||
const functionNode = (0, getParentFunctionNode_1.getParentFunctionNode)(returnNode);
|
||||
/* istanbul ignore if */ if (!functionNode) {
|
||||
return;
|
||||
}
|
||||
// function has an explicit return type, so ensure it's a safe return
|
||||
const returnNodeType = (0, util_1.getConstrainedTypeAtLocation)(services, returnNode);
|
||||
const functionTSNode = services.esTreeNodeToTSNodeMap.get(functionNode);
|
||||
// function expressions will not have their return type modified based on receiver typing
|
||||
// so we have to use the contextual typing in these cases, i.e.
|
||||
// const foo1: () => Set<string> = () => new Set<any>();
|
||||
// the return type of the arrow function is Set<any> even though the variable is typed as Set<string>
|
||||
let functionType = ts.isFunctionExpression(functionTSNode) ||
|
||||
ts.isArrowFunction(functionTSNode)
|
||||
? (0, util_1.getContextualType)(checker, functionTSNode)
|
||||
: services.getTypeAtLocation(functionNode);
|
||||
if (!functionType) {
|
||||
functionType = services.getTypeAtLocation(functionNode);
|
||||
}
|
||||
const callSignatures = tsutils.getCallSignaturesOfType(functionType);
|
||||
// If there is an explicit type annotation *and* that type matches the actual
|
||||
// function return type, we shouldn't complain (it's intentional, even if unsafe)
|
||||
if (functionTSNode.type) {
|
||||
for (const signature of callSignatures) {
|
||||
const signatureReturnType = signature.getReturnType();
|
||||
if (returnNodeType === signatureReturnType ||
|
||||
(0, util_1.isTypeFlagSet)(signatureReturnType, ts.TypeFlags.Any | ts.TypeFlags.Unknown)) {
|
||||
return;
|
||||
}
|
||||
if (functionNode.async) {
|
||||
const awaitedSignatureReturnType = checker.getAwaitedType(signatureReturnType);
|
||||
const awaitedReturnNodeType = checker.getAwaitedType(returnNodeType);
|
||||
if (awaitedReturnNodeType === awaitedSignatureReturnType ||
|
||||
(awaitedSignatureReturnType &&
|
||||
(0, util_1.isTypeFlagSet)(awaitedSignatureReturnType, ts.TypeFlags.Any | ts.TypeFlags.Unknown))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (anyType !== util_1.AnyType.Safe) {
|
||||
// Allow cases when the declared return type of the function is either unknown or unknown[]
|
||||
// and the function is returning any or any[].
|
||||
for (const signature of callSignatures) {
|
||||
const functionReturnType = signature.getReturnType();
|
||||
if (anyType === util_1.AnyType.Any &&
|
||||
(0, util_1.isTypeUnknownType)(functionReturnType)) {
|
||||
return;
|
||||
}
|
||||
if (anyType === util_1.AnyType.AnyArray &&
|
||||
(0, util_1.isTypeUnknownArrayType)(functionReturnType, checker)) {
|
||||
return;
|
||||
}
|
||||
const awaitedType = checker.getAwaitedType(functionReturnType);
|
||||
if (awaitedType &&
|
||||
anyType === util_1.AnyType.PromiseAny &&
|
||||
(0, util_1.isTypeUnknownType)(awaitedType)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (anyType === util_1.AnyType.PromiseAny && !functionNode.async) {
|
||||
return;
|
||||
}
|
||||
let messageId = 'unsafeReturn';
|
||||
const isErrorType = tsutils.isIntrinsicErrorType(returnNodeType);
|
||||
if (!isNoImplicitThis) {
|
||||
// `return this`
|
||||
const thisExpression = (0, util_1.getThisExpression)(returnNode);
|
||||
if (thisExpression &&
|
||||
(0, util_1.isTypeAnyType)((0, util_1.getConstrainedTypeAtLocation)(services, thisExpression))) {
|
||||
messageId = 'unsafeReturnThis';
|
||||
}
|
||||
}
|
||||
// If the function return type was not unknown/unknown[], mark usage as unsafeReturn.
|
||||
return context.report({
|
||||
node: reportingNode,
|
||||
messageId,
|
||||
data: {
|
||||
type: isErrorType
|
||||
? 'error'
|
||||
: anyType === util_1.AnyType.Any
|
||||
? '`any`'
|
||||
: anyType === util_1.AnyType.PromiseAny
|
||||
? '`Promise<any>`'
|
||||
: '`any[]`',
|
||||
},
|
||||
});
|
||||
}
|
||||
const signature = functionType.getCallSignatures().at(0);
|
||||
if (signature) {
|
||||
const functionReturnType = signature.getReturnType();
|
||||
const result = (0, util_1.isUnsafeAssignment)(returnNodeType, functionReturnType, checker, returnNode);
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
const { receiver, sender } = result;
|
||||
return context.report({
|
||||
node: reportingNode,
|
||||
messageId: 'unsafeReturnAssignment',
|
||||
data: {
|
||||
receiver: checker.typeToString(receiver),
|
||||
sender: checker.typeToString(sender),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
return {
|
||||
'ArrowFunctionExpression > :not(BlockStatement).body': checkReturn,
|
||||
ReturnStatement(node) {
|
||||
const argument = node.argument;
|
||||
if (!argument) {
|
||||
return;
|
||||
}
|
||||
checkReturn(argument, node);
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
//# sourceMappingURL=no-unsafe-return.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"no-unsafe-return.js","sourceRoot":"","sources":["../../src/rules/no-unsafe-return.ts"],"names":[],"mappings":"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"}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
const ts = __importStar(require("typescript"));
|
||||
const util_1 = require("../util");
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'only-throw-error',
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Disallow throwing non-`Error` values as exceptions',
|
||||
extendsBaseRule: 'no-throw-literal',
|
||||
recommended: 'recommended',
|
||||
requiresTypeChecking: true,
|
||||
},
|
||||
messages: {
|
||||
object: 'Expected an error object to be thrown.',
|
||||
undef: 'Do not throw undefined.',
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
allow: {
|
||||
...util_1.typeOrValueSpecifiersSchema,
|
||||
description: 'Type specifiers that can be thrown.',
|
||||
},
|
||||
allowThrowingAny: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to always allow throwing values typed as `any`.',
|
||||
},
|
||||
allowThrowingUnknown: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to always allow throwing values typed as `unknown`.',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultOptions: [
|
||||
{
|
||||
allow: [],
|
||||
allowThrowingAny: true,
|
||||
allowThrowingUnknown: true,
|
||||
},
|
||||
],
|
||||
create(context, [options]) {
|
||||
const services = (0, util_1.getParserServices)(context);
|
||||
const allow = options.allow;
|
||||
function checkThrowArgument(node) {
|
||||
if (node.type === utils_1.AST_NODE_TYPES.AwaitExpression ||
|
||||
node.type === utils_1.AST_NODE_TYPES.YieldExpression) {
|
||||
return;
|
||||
}
|
||||
const type = services.getTypeAtLocation(node);
|
||||
if ((0, util_1.typeMatchesSomeSpecifier)(type, allow, services.program)) {
|
||||
return;
|
||||
}
|
||||
if (type.flags & ts.TypeFlags.Undefined) {
|
||||
context.report({ node, messageId: 'undef' });
|
||||
return;
|
||||
}
|
||||
if (options.allowThrowingAny && (0, util_1.isTypeAnyType)(type)) {
|
||||
return;
|
||||
}
|
||||
if (options.allowThrowingUnknown && (0, util_1.isTypeUnknownType)(type)) {
|
||||
return;
|
||||
}
|
||||
if ((0, util_1.isErrorLike)(services.program, type)) {
|
||||
return;
|
||||
}
|
||||
context.report({ node, messageId: 'object' });
|
||||
}
|
||||
return {
|
||||
ThrowStatement(node) {
|
||||
checkThrowArgument(node.argument);
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
//# sourceMappingURL=only-throw-error.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"only-throw-error.js","sourceRoot":"","sources":["../../src/rules/only-throw-error.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAEA,oDAA0D;AAC1D,+CAAiC;AAIjC,kCAQiB;AAYjB,kBAAe,IAAA,iBAAU,EAAsB;IAC7C,IAAI,EAAE,kBAAkB;IACxB,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EAAE,oDAAoD;YACjE,eAAe,EAAE,kBAAkB;YACnC,WAAW,EAAE,aAAa;YAC1B,oBAAoB,EAAE,IAAI;SAC3B;QACD,QAAQ,EAAE;YACR,MAAM,EAAE,wCAAwC;YAChD,KAAK,EAAE,yBAAyB;SACjC;QACD,MAAM,EAAE;YACN;gBACE,IAAI,EAAE,QAAQ;gBACd,oBAAoB,EAAE,KAAK;gBAC3B,UAAU,EAAE;oBACV,KAAK,EAAE;wBACL,GAAG,kCAA2B;wBAC9B,WAAW,EAAE,qCAAqC;qBACnD;oBACD,gBAAgB,EAAE;wBAChB,IAAI,EAAE,SAAS;wBACf,WAAW,EACT,yDAAyD;qBAC5D;oBACD,oBAAoB,EAAE;wBACpB,IAAI,EAAE,SAAS;wBACf,WAAW,EACT,6DAA6D;qBAChE;iBACF;aACF;SACF;KACF;IACD,cAAc,EAAE;QACd;YACE,KAAK,EAAE,EAAE;YACT,gBAAgB,EAAE,IAAI;YACtB,oBAAoB,EAAE,IAAI;SAC3B;KACF;IACD,MAAM,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC;QACvB,MAAM,QAAQ,GAAG,IAAA,wBAAiB,EAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5B,SAAS,kBAAkB,CAAC,IAAmB;YAC7C,IACE,IAAI,CAAC,IAAI,KAAK,sBAAc,CAAC,eAAe;gBAC5C,IAAI,CAAC,IAAI,KAAK,sBAAc,CAAC,eAAe,EAC5C,CAAC;gBACD,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAE9C,IAAI,IAAA,+BAAwB,EAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5D,OAAO;YACT,CAAC;YAED,IAAI,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;gBACxC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;gBAC7C,OAAO;YACT,CAAC;YAED,IAAI,OAAO,CAAC,gBAAgB,IAAI,IAAA,oBAAa,EAAC,IAAI,CAAC,EAAE,CAAC;gBACpD,OAAO;YACT,CAAC;YAED,IAAI,OAAO,CAAC,oBAAoB,IAAI,IAAA,wBAAiB,EAAC,IAAI,CAAC,EAAE,CAAC;gBAC5D,OAAO;YACT,CAAC;YAED,IAAI,IAAA,kBAAW,EAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;gBACxC,OAAO;YACT,CAAC;YAED,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;QAChD,CAAC;QAED,OAAO;YACL,cAAc,CAAC,IAAI;gBACjB,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACpC,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
||||
Generated
Vendored
+419
@@ -0,0 +1,419 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
const tsutils = __importStar(require("ts-api-utils"));
|
||||
const ts = __importStar(require("typescript"));
|
||||
const util_1 = require("../util");
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'prefer-nullish-coalescing',
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'Enforce using the nullish coalescing operator instead of logical assignments or chaining',
|
||||
recommended: 'stylistic',
|
||||
requiresTypeChecking: true,
|
||||
},
|
||||
hasSuggestions: true,
|
||||
messages: {
|
||||
noStrictNullCheck: 'This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.',
|
||||
preferNullishOverOr: 'Prefer using nullish coalescing operator (`??{{ equals }}`) instead of a logical {{ description }} (`||{{ equals }}`), as it is a safer operator.',
|
||||
preferNullishOverTernary: 'Prefer using nullish coalescing operator (`??{{ equals }}`) instead of a ternary expression, as it is simpler to read.',
|
||||
suggestNullish: 'Fix to nullish coalescing operator (`??{{ equals }}`).',
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: {
|
||||
type: 'boolean',
|
||||
description: 'Unless this is set to `true`, the rule will error on every file whose `tsconfig.json` does _not_ have the `strictNullChecks` compiler option (or `strict`) set to `true`.',
|
||||
},
|
||||
ignoreBooleanCoercion: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to ignore arguments to the `Boolean` constructor',
|
||||
},
|
||||
ignoreConditionalTests: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to ignore cases that are located within a conditional test.',
|
||||
},
|
||||
ignoreMixedLogicalExpressions: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to ignore any logical or expressions that are part of a mixed logical expression (with `&&`).',
|
||||
},
|
||||
ignorePrimitives: {
|
||||
description: 'Whether to ignore all (`true`) or some (an object with properties) primitive types.',
|
||||
oneOf: [
|
||||
{
|
||||
type: 'object',
|
||||
description: 'Which primitives types may be ignored.',
|
||||
properties: {
|
||||
bigint: {
|
||||
type: 'boolean',
|
||||
description: 'Ignore bigint primitive types.',
|
||||
},
|
||||
boolean: {
|
||||
type: 'boolean',
|
||||
description: 'Ignore boolean primitive types.',
|
||||
},
|
||||
number: {
|
||||
type: 'boolean',
|
||||
description: 'Ignore number primitive types.',
|
||||
},
|
||||
string: {
|
||||
type: 'boolean',
|
||||
description: 'Ignore string primitive types.',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'boolean',
|
||||
description: 'Ignore all primitive types.',
|
||||
enum: [true],
|
||||
},
|
||||
],
|
||||
},
|
||||
ignoreTernaryTests: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to ignore any ternary expressions that could be simplified by using the nullish coalescing operator.',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultOptions: [
|
||||
{
|
||||
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: false,
|
||||
ignoreBooleanCoercion: false,
|
||||
ignoreConditionalTests: true,
|
||||
ignoreMixedLogicalExpressions: false,
|
||||
ignorePrimitives: {
|
||||
bigint: false,
|
||||
boolean: false,
|
||||
number: false,
|
||||
string: false,
|
||||
},
|
||||
ignoreTernaryTests: false,
|
||||
},
|
||||
],
|
||||
create(context, [{ allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing, ignoreBooleanCoercion, ignoreConditionalTests, ignoreMixedLogicalExpressions, ignorePrimitives, ignoreTernaryTests, },]) {
|
||||
const parserServices = (0, util_1.getParserServices)(context);
|
||||
const compilerOptions = parserServices.program.getCompilerOptions();
|
||||
const checker = parserServices.program.getTypeChecker();
|
||||
const isStrictNullChecks = tsutils.isStrictCompilerOptionEnabled(compilerOptions, 'strictNullChecks');
|
||||
if (!isStrictNullChecks &&
|
||||
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing !== true) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: { column: 0, line: 0 },
|
||||
end: { column: 0, line: 0 },
|
||||
},
|
||||
messageId: 'noStrictNullCheck',
|
||||
});
|
||||
}
|
||||
// todo: rename to something more specific?
|
||||
function checkAssignmentOrLogicalExpression(node, description, equals) {
|
||||
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);
|
||||
const type = checker.getTypeAtLocation(tsNode.left);
|
||||
if (!(0, util_1.isTypeFlagSet)(type, ts.TypeFlags.Null | ts.TypeFlags.Undefined)) {
|
||||
return;
|
||||
}
|
||||
if (ignoreConditionalTests === true && isConditionalTest(node)) {
|
||||
return;
|
||||
}
|
||||
if (ignoreMixedLogicalExpressions === true &&
|
||||
isMixedLogicalExpression(node)) {
|
||||
return;
|
||||
}
|
||||
// https://github.com/typescript-eslint/typescript-eslint/issues/5439
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
const ignorableFlags = [
|
||||
(ignorePrimitives === true || ignorePrimitives.bigint) &&
|
||||
ts.TypeFlags.BigIntLike,
|
||||
(ignorePrimitives === true || ignorePrimitives.boolean) &&
|
||||
ts.TypeFlags.BooleanLike,
|
||||
(ignorePrimitives === true || ignorePrimitives.number) &&
|
||||
ts.TypeFlags.NumberLike,
|
||||
(ignorePrimitives === true || ignorePrimitives.string) &&
|
||||
ts.TypeFlags.StringLike,
|
||||
]
|
||||
.filter((flag) => typeof flag === 'number')
|
||||
.reduce((previous, flag) => previous | flag, 0);
|
||||
if (type.flags !== ts.TypeFlags.Null &&
|
||||
type.flags !== ts.TypeFlags.Undefined &&
|
||||
type.types.some(t => tsutils
|
||||
.intersectionTypeParts(t)
|
||||
.some(t => tsutils.isTypeFlagSet(t, ignorableFlags)))) {
|
||||
return;
|
||||
}
|
||||
/* eslint-enable @typescript-eslint/no-non-null-assertion */
|
||||
const barBarOperator = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(node.left, token => token.type === utils_1.AST_TOKEN_TYPES.Punctuator &&
|
||||
token.value === node.operator), util_1.NullThrowsReasons.MissingToken('operator', node.type));
|
||||
function* fix(fixer) {
|
||||
if ((0, util_1.isLogicalOrOperator)(node.parent)) {
|
||||
// '&&' and '??' operations cannot be mixed without parentheses (e.g. a && b ?? c)
|
||||
if (node.left.type === utils_1.AST_NODE_TYPES.LogicalExpression &&
|
||||
!(0, util_1.isLogicalOrOperator)(node.left.left)) {
|
||||
yield fixer.insertTextBefore(node.left.right, '(');
|
||||
}
|
||||
else {
|
||||
yield fixer.insertTextBefore(node.left, '(');
|
||||
}
|
||||
yield fixer.insertTextAfter(node.right, ')');
|
||||
}
|
||||
yield fixer.replaceText(barBarOperator, node.operator.replace('||', '??'));
|
||||
}
|
||||
context.report({
|
||||
node: barBarOperator,
|
||||
messageId: 'preferNullishOverOr',
|
||||
data: { description, equals },
|
||||
suggest: [
|
||||
{
|
||||
messageId: 'suggestNullish',
|
||||
data: { equals },
|
||||
fix,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
return {
|
||||
'AssignmentExpression[operator = "||="]'(node) {
|
||||
checkAssignmentOrLogicalExpression(node, 'assignment', '=');
|
||||
},
|
||||
ConditionalExpression(node) {
|
||||
if (ignoreTernaryTests) {
|
||||
return;
|
||||
}
|
||||
let operator;
|
||||
let nodesInsideTestExpression = [];
|
||||
if (node.test.type === utils_1.AST_NODE_TYPES.BinaryExpression) {
|
||||
nodesInsideTestExpression = [node.test.left, node.test.right];
|
||||
if (node.test.operator === '==' ||
|
||||
node.test.operator === '!=' ||
|
||||
node.test.operator === '===' ||
|
||||
node.test.operator === '!==') {
|
||||
operator = node.test.operator;
|
||||
}
|
||||
}
|
||||
else if (node.test.type === utils_1.AST_NODE_TYPES.LogicalExpression &&
|
||||
node.test.left.type === utils_1.AST_NODE_TYPES.BinaryExpression &&
|
||||
node.test.right.type === utils_1.AST_NODE_TYPES.BinaryExpression) {
|
||||
nodesInsideTestExpression = [
|
||||
node.test.left.left,
|
||||
node.test.left.right,
|
||||
node.test.right.left,
|
||||
node.test.right.right,
|
||||
];
|
||||
if (['||', '||='].includes(node.test.operator)) {
|
||||
if (node.test.left.operator === '===' &&
|
||||
node.test.right.operator === '===') {
|
||||
operator = '===';
|
||||
}
|
||||
else if (((node.test.left.operator === '===' ||
|
||||
node.test.right.operator === '===') &&
|
||||
(node.test.left.operator === '==' ||
|
||||
node.test.right.operator === '==')) ||
|
||||
(node.test.left.operator === '==' &&
|
||||
node.test.right.operator === '==')) {
|
||||
operator = '==';
|
||||
}
|
||||
}
|
||||
else if (node.test.operator === '&&') {
|
||||
if (node.test.left.operator === '!==' &&
|
||||
node.test.right.operator === '!==') {
|
||||
operator = '!==';
|
||||
}
|
||||
else if (((node.test.left.operator === '!==' ||
|
||||
node.test.right.operator === '!==') &&
|
||||
(node.test.left.operator === '!=' ||
|
||||
node.test.right.operator === '!=')) ||
|
||||
(node.test.left.operator === '!=' &&
|
||||
node.test.right.operator === '!=')) {
|
||||
operator = '!=';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!operator) {
|
||||
return;
|
||||
}
|
||||
let identifier;
|
||||
let hasUndefinedCheck = false;
|
||||
let hasNullCheck = false;
|
||||
// we check that the test only contains null, undefined and the identifier
|
||||
for (const testNode of nodesInsideTestExpression) {
|
||||
if ((0, util_1.isNullLiteral)(testNode)) {
|
||||
hasNullCheck = true;
|
||||
}
|
||||
else if ((0, util_1.isUndefinedIdentifier)(testNode)) {
|
||||
hasUndefinedCheck = true;
|
||||
}
|
||||
else if ((operator === '!==' || operator === '!=') &&
|
||||
(0, util_1.isNodeEqual)(testNode, node.consequent)) {
|
||||
identifier = testNode;
|
||||
}
|
||||
else if ((operator === '===' || operator === '==') &&
|
||||
(0, util_1.isNodeEqual)(testNode, node.alternate)) {
|
||||
identifier = testNode;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!identifier) {
|
||||
return;
|
||||
}
|
||||
const isFixable = (() => {
|
||||
// it is fixable if we check for both null and undefined, or not if neither
|
||||
if (hasUndefinedCheck === hasNullCheck) {
|
||||
return hasUndefinedCheck;
|
||||
}
|
||||
// it is fixable if we loosely check for either null or undefined
|
||||
if (operator === '==' || operator === '!=') {
|
||||
return true;
|
||||
}
|
||||
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(identifier);
|
||||
const type = checker.getTypeAtLocation(tsNode);
|
||||
const flags = (0, util_1.getTypeFlags)(type);
|
||||
if (flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) {
|
||||
return false;
|
||||
}
|
||||
const hasNullType = (flags & ts.TypeFlags.Null) !== 0;
|
||||
// it is fixable if we check for undefined and the type is not nullable
|
||||
if (hasUndefinedCheck && !hasNullType) {
|
||||
return true;
|
||||
}
|
||||
const hasUndefinedType = (flags & ts.TypeFlags.Undefined) !== 0;
|
||||
// it is fixable if we check for null and the type can't be undefined
|
||||
return hasNullCheck && !hasUndefinedType;
|
||||
})();
|
||||
if (isFixable) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'preferNullishOverTernary',
|
||||
// TODO: also account for = in the ternary clause
|
||||
data: { equals: '' },
|
||||
suggest: [
|
||||
{
|
||||
messageId: 'suggestNullish',
|
||||
data: { equals: '' },
|
||||
fix(fixer) {
|
||||
const [left, right] = operator === '===' || operator === '=='
|
||||
? [node.alternate, node.consequent]
|
||||
: [node.consequent, node.alternate];
|
||||
return fixer.replaceText(node, `${(0, util_1.getTextWithParentheses)(context.sourceCode, left)} ?? ${(0, util_1.getTextWithParentheses)(context.sourceCode, right)}`);
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
},
|
||||
'LogicalExpression[operator = "||"]'(node) {
|
||||
if (ignoreBooleanCoercion === true &&
|
||||
isBooleanConstructorContext(node, context)) {
|
||||
return;
|
||||
}
|
||||
checkAssignmentOrLogicalExpression(node, 'or', '');
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
function isConditionalTest(node) {
|
||||
const parent = node.parent;
|
||||
if (parent == null) {
|
||||
return false;
|
||||
}
|
||||
if (parent.type === utils_1.AST_NODE_TYPES.LogicalExpression) {
|
||||
return isConditionalTest(parent);
|
||||
}
|
||||
if (parent.type === utils_1.AST_NODE_TYPES.ConditionalExpression &&
|
||||
(parent.consequent === node || parent.alternate === node)) {
|
||||
return isConditionalTest(parent);
|
||||
}
|
||||
if (parent.type === utils_1.AST_NODE_TYPES.SequenceExpression &&
|
||||
parent.expressions.at(-1) === node) {
|
||||
return isConditionalTest(parent);
|
||||
}
|
||||
if ((parent.type === utils_1.AST_NODE_TYPES.ConditionalExpression ||
|
||||
parent.type === utils_1.AST_NODE_TYPES.DoWhileStatement ||
|
||||
parent.type === utils_1.AST_NODE_TYPES.IfStatement ||
|
||||
parent.type === utils_1.AST_NODE_TYPES.ForStatement ||
|
||||
parent.type === utils_1.AST_NODE_TYPES.WhileStatement) &&
|
||||
parent.test === node) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function isBooleanConstructorContext(node, context) {
|
||||
const parent = node.parent;
|
||||
if (parent == null) {
|
||||
return false;
|
||||
}
|
||||
if (parent.type === utils_1.AST_NODE_TYPES.LogicalExpression) {
|
||||
return isBooleanConstructorContext(parent, context);
|
||||
}
|
||||
if (parent.type === utils_1.AST_NODE_TYPES.ConditionalExpression &&
|
||||
(parent.consequent === node || parent.alternate === node)) {
|
||||
return isBooleanConstructorContext(parent, context);
|
||||
}
|
||||
if (parent.type === utils_1.AST_NODE_TYPES.SequenceExpression &&
|
||||
parent.expressions.at(-1) === node) {
|
||||
return isBooleanConstructorContext(parent, context);
|
||||
}
|
||||
return isBuiltInBooleanCall(parent, context);
|
||||
}
|
||||
function isBuiltInBooleanCall(node, context) {
|
||||
if (node.type === utils_1.AST_NODE_TYPES.CallExpression &&
|
||||
node.callee.type === utils_1.AST_NODE_TYPES.Identifier &&
|
||||
// eslint-disable-next-line @typescript-eslint/internal/prefer-ast-types-enum
|
||||
node.callee.name === 'Boolean' &&
|
||||
node.arguments[0]) {
|
||||
const scope = context.sourceCode.getScope(node);
|
||||
const variable = scope.set.get(utils_1.AST_TOKEN_TYPES.Boolean);
|
||||
return variable == null || variable.defs.length === 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function isMixedLogicalExpression(node) {
|
||||
const seen = new Set();
|
||||
const queue = [node.parent, node.left, node.right];
|
||||
for (const current of queue) {
|
||||
if (seen.has(current)) {
|
||||
continue;
|
||||
}
|
||||
seen.add(current);
|
||||
if (current.type === utils_1.AST_NODE_TYPES.LogicalExpression) {
|
||||
if (current.operator === '&&') {
|
||||
return true;
|
||||
}
|
||||
else if (['||', '||='].includes(current.operator)) {
|
||||
// check the pieces of the node to catch cases like `a || b || c && d`
|
||||
queue.push(current.parent, current.left, current.right);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//# sourceMappingURL=prefer-nullish-coalescing.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
node_modules/@typescript-eslint/eslint-plugin/dist/rules/prefer-optional-chain-utils/analyzeChain.js
Generated
Vendored
+457
@@ -0,0 +1,457 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.analyzeChain = analyzeChain;
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
const ts_api_utils_1 = require("ts-api-utils");
|
||||
const ts = __importStar(require("typescript"));
|
||||
const util_1 = require("../../util");
|
||||
const checkNullishAndReport_1 = require("./checkNullishAndReport");
|
||||
const compareNodes_1 = require("./compareNodes");
|
||||
function includesType(parserServices, node, typeFlagIn) {
|
||||
const typeFlag = typeFlagIn | ts.TypeFlags.Any | ts.TypeFlags.Unknown;
|
||||
const types = (0, ts_api_utils_1.unionTypeParts)(parserServices.getTypeAtLocation(node));
|
||||
for (const type of types) {
|
||||
if ((0, util_1.isTypeFlagSet)(type, typeFlag)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const analyzeAndChainOperand = (parserServices, operand, index, chain) => {
|
||||
switch (operand.comparisonType) {
|
||||
case "Boolean" /* NullishComparisonType.Boolean */: {
|
||||
const nextOperand = chain.at(index + 1);
|
||||
if (nextOperand?.comparisonType ===
|
||||
"NotStrictEqualNull" /* NullishComparisonType.NotStrictEqualNull */ &&
|
||||
operand.comparedName.type === utils_1.AST_NODE_TYPES.Identifier) {
|
||||
return null;
|
||||
}
|
||||
return [operand];
|
||||
}
|
||||
case "NotEqualNullOrUndefined" /* NullishComparisonType.NotEqualNullOrUndefined */:
|
||||
return [operand];
|
||||
case "NotStrictEqualNull" /* NullishComparisonType.NotStrictEqualNull */: {
|
||||
// handle `x !== null && x !== undefined`
|
||||
const nextOperand = chain.at(index + 1);
|
||||
if (nextOperand?.comparisonType ===
|
||||
"NotStrictEqualUndefined" /* NullishComparisonType.NotStrictEqualUndefined */ &&
|
||||
(0, compareNodes_1.compareNodes)(operand.comparedName, nextOperand.comparedName) ===
|
||||
"Equal" /* NodeComparisonResult.Equal */) {
|
||||
return [operand, nextOperand];
|
||||
}
|
||||
if (includesType(parserServices, operand.comparedName, ts.TypeFlags.Undefined)) {
|
||||
// we know the next operand is not an `undefined` check and that this
|
||||
// operand includes `undefined` - which means that making this an
|
||||
// optional chain would change the runtime behavior of the expression
|
||||
return null;
|
||||
}
|
||||
return [operand];
|
||||
}
|
||||
case "NotStrictEqualUndefined" /* NullishComparisonType.NotStrictEqualUndefined */: {
|
||||
// handle `x !== undefined && x !== null`
|
||||
const nextOperand = chain.at(index + 1);
|
||||
if (nextOperand?.comparisonType ===
|
||||
"NotStrictEqualNull" /* NullishComparisonType.NotStrictEqualNull */ &&
|
||||
(0, compareNodes_1.compareNodes)(operand.comparedName, nextOperand.comparedName) ===
|
||||
"Equal" /* NodeComparisonResult.Equal */) {
|
||||
return [operand, nextOperand];
|
||||
}
|
||||
if (includesType(parserServices, operand.comparedName, ts.TypeFlags.Null)) {
|
||||
// we know the next operand is not a `null` check and that this
|
||||
// operand includes `null` - which means that making this an
|
||||
// optional chain would change the runtime behavior of the expression
|
||||
return null;
|
||||
}
|
||||
return [operand];
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
const analyzeOrChainOperand = (parserServices, operand, index, chain) => {
|
||||
switch (operand.comparisonType) {
|
||||
case "NotBoolean" /* NullishComparisonType.NotBoolean */:
|
||||
case "EqualNullOrUndefined" /* NullishComparisonType.EqualNullOrUndefined */:
|
||||
return [operand];
|
||||
case "StrictEqualNull" /* NullishComparisonType.StrictEqualNull */: {
|
||||
// handle `x === null || x === undefined`
|
||||
const nextOperand = chain.at(index + 1);
|
||||
if (nextOperand?.comparisonType ===
|
||||
"StrictEqualUndefined" /* NullishComparisonType.StrictEqualUndefined */ &&
|
||||
(0, compareNodes_1.compareNodes)(operand.comparedName, nextOperand.comparedName) ===
|
||||
"Equal" /* NodeComparisonResult.Equal */) {
|
||||
return [operand, nextOperand];
|
||||
}
|
||||
if (includesType(parserServices, operand.comparedName, ts.TypeFlags.Undefined)) {
|
||||
// we know the next operand is not an `undefined` check and that this
|
||||
// operand includes `undefined` - which means that making this an
|
||||
// optional chain would change the runtime behavior of the expression
|
||||
return null;
|
||||
}
|
||||
return [operand];
|
||||
}
|
||||
case "StrictEqualUndefined" /* NullishComparisonType.StrictEqualUndefined */: {
|
||||
// handle `x === undefined || x === null`
|
||||
const nextOperand = chain.at(index + 1);
|
||||
if (nextOperand?.comparisonType === "StrictEqualNull" /* NullishComparisonType.StrictEqualNull */ &&
|
||||
(0, compareNodes_1.compareNodes)(operand.comparedName, nextOperand.comparedName) ===
|
||||
"Equal" /* NodeComparisonResult.Equal */) {
|
||||
return [operand, nextOperand];
|
||||
}
|
||||
if (includesType(parserServices, operand.comparedName, ts.TypeFlags.Null)) {
|
||||
// we know the next operand is not a `null` check and that this
|
||||
// operand includes `null` - which means that making this an
|
||||
// optional chain would change the runtime behavior of the expression
|
||||
return null;
|
||||
}
|
||||
return [operand];
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Returns the range that needs to be reported from the chain.
|
||||
* @param chain The chain of logical expressions.
|
||||
* @param boundary The boundary range that the range to report cannot fall outside.
|
||||
* @param sourceCode The source code to get tokens.
|
||||
* @returns The range to report.
|
||||
*/
|
||||
function getReportRange(chain, boundary, sourceCode) {
|
||||
const leftNode = chain[0].node;
|
||||
const rightNode = chain[chain.length - 1].node;
|
||||
let leftMost = (0, util_1.nullThrows)(sourceCode.getFirstToken(leftNode), util_1.NullThrowsReasons.MissingToken('any token', leftNode.type));
|
||||
let rightMost = (0, util_1.nullThrows)(sourceCode.getLastToken(rightNode), util_1.NullThrowsReasons.MissingToken('any token', rightNode.type));
|
||||
while (leftMost.range[0] > boundary[0]) {
|
||||
const token = sourceCode.getTokenBefore(leftMost);
|
||||
if (!token || !(0, util_1.isOpeningParenToken)(token) || token.range[0] < boundary[0]) {
|
||||
break;
|
||||
}
|
||||
leftMost = token;
|
||||
}
|
||||
while (rightMost.range[1] < boundary[1]) {
|
||||
const token = sourceCode.getTokenAfter(rightMost);
|
||||
if (!token || !(0, util_1.isClosingParenToken)(token) || token.range[1] > boundary[1]) {
|
||||
break;
|
||||
}
|
||||
rightMost = token;
|
||||
}
|
||||
return [leftMost.range[0], rightMost.range[1]];
|
||||
}
|
||||
function getReportDescriptor(sourceCode, parserServices, node, operator, options, chain) {
|
||||
const lastOperand = chain[chain.length - 1];
|
||||
let useSuggestionFixer;
|
||||
if (options.allowPotentiallyUnsafeFixesThatModifyTheReturnTypeIKnowWhatImDoing ===
|
||||
true) {
|
||||
// user has opted-in to the unsafe behavior
|
||||
useSuggestionFixer = false;
|
||||
}
|
||||
// optional chain specifically will union `undefined` into the final type
|
||||
// so we need to make sure that there is at least one operand that includes
|
||||
// `undefined`, or else we're going to change the final type - which is
|
||||
// unsafe and might cause downstream type errors.
|
||||
else if (lastOperand.comparisonType === "EqualNullOrUndefined" /* NullishComparisonType.EqualNullOrUndefined */ ||
|
||||
lastOperand.comparisonType ===
|
||||
"NotEqualNullOrUndefined" /* NullishComparisonType.NotEqualNullOrUndefined */ ||
|
||||
lastOperand.comparisonType === "StrictEqualUndefined" /* NullishComparisonType.StrictEqualUndefined */ ||
|
||||
lastOperand.comparisonType ===
|
||||
"NotStrictEqualUndefined" /* NullishComparisonType.NotStrictEqualUndefined */ ||
|
||||
(operator === '||' &&
|
||||
lastOperand.comparisonType === "NotBoolean" /* NullishComparisonType.NotBoolean */)) {
|
||||
// we know the last operand is an equality check - so the change in types
|
||||
// DOES NOT matter and will not change the runtime result or cause a type
|
||||
// check error
|
||||
useSuggestionFixer = false;
|
||||
}
|
||||
else {
|
||||
useSuggestionFixer = true;
|
||||
for (const operand of chain) {
|
||||
if (includesType(parserServices, operand.node, ts.TypeFlags.Undefined)) {
|
||||
useSuggestionFixer = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// TODO - we could further reduce the false-positive rate of this check by
|
||||
// checking for cases where the change in types don't matter like
|
||||
// the test location of an if/while/etc statement.
|
||||
// but it's quite complex to do this without false-negatives, so
|
||||
// for now we'll just be over-eager with our matching.
|
||||
//
|
||||
// it's MUCH better to false-positive here and only provide a
|
||||
// suggestion fixer, rather than false-negative and autofix to
|
||||
// broken code.
|
||||
}
|
||||
// In its most naive form we could just slap `?.` for every single part of the
|
||||
// chain. However this would be undesirable because it'd create unnecessary
|
||||
// conditions in the user's code where there were none before - and it would
|
||||
// cause errors with rules like our `no-unnecessary-condition`.
|
||||
//
|
||||
// Instead we want to include the minimum number of `?.` required to correctly
|
||||
// unify the code into a single chain. Naively you might think that we can
|
||||
// just take the final operand add `?.` after the locations from the previous
|
||||
// operands - however this won't be correct either because earlier operands
|
||||
// can include a necessary `?.` that's not needed or included in a later
|
||||
// operand.
|
||||
//
|
||||
// So instead what we need to do is to start at the first operand and
|
||||
// iteratively diff it against the next operand, and add the difference to the
|
||||
// first operand.
|
||||
//
|
||||
// eg
|
||||
// `foo && foo.bar && foo.bar.baz?.bam && foo.bar.baz.bam()`
|
||||
// 1) `foo`
|
||||
// 2) diff(`foo`, `foo.bar`) = `.bar`
|
||||
// 3) result = `foo?.bar`
|
||||
// 4) diff(`foo.bar`, `foo.bar.baz?.bam`) = `.baz?.bam`
|
||||
// 5) result = `foo?.bar?.baz?.bam`
|
||||
// 6) diff(`foo.bar.baz?.bam`, `foo.bar.baz.bam()`) = `()`
|
||||
// 7) result = `foo?.bar?.baz?.bam?.()`
|
||||
const parts = [];
|
||||
for (const current of chain) {
|
||||
const nextOperand = flattenChainExpression(sourceCode, current.comparedName);
|
||||
const diff = nextOperand.slice(parts.length);
|
||||
if (diff.length > 0) {
|
||||
if (parts.length > 0) {
|
||||
// we need to make the first operand of the diff optional so it matches the
|
||||
// logic before merging
|
||||
// foo.bar && foo.bar.baz
|
||||
// diff = .baz
|
||||
// result = foo.bar?.baz
|
||||
diff[0].optional = true;
|
||||
}
|
||||
parts.push(...diff);
|
||||
}
|
||||
}
|
||||
let newCode = parts
|
||||
.map(part => {
|
||||
let str = '';
|
||||
if (part.optional) {
|
||||
str += '?.';
|
||||
}
|
||||
else {
|
||||
if (part.nonNull) {
|
||||
str += '!';
|
||||
}
|
||||
if (part.requiresDot) {
|
||||
str += '.';
|
||||
}
|
||||
}
|
||||
if (part.precedence !== util_1.OperatorPrecedence.Invalid &&
|
||||
part.precedence < util_1.OperatorPrecedence.Member) {
|
||||
str += `(${part.text})`;
|
||||
}
|
||||
else {
|
||||
str += part.text;
|
||||
}
|
||||
return str;
|
||||
})
|
||||
.join('');
|
||||
if (lastOperand.node.type === utils_1.AST_NODE_TYPES.BinaryExpression) {
|
||||
// retain the ending comparison for cases like
|
||||
// x && x.a != null
|
||||
// x && typeof x.a !== 'undefined'
|
||||
const operator = lastOperand.node.operator;
|
||||
const { left, right } = (() => {
|
||||
if (lastOperand.isYoda) {
|
||||
const unaryOperator = lastOperand.node.right.type === utils_1.AST_NODE_TYPES.UnaryExpression
|
||||
? `${lastOperand.node.right.operator} `
|
||||
: '';
|
||||
return {
|
||||
left: sourceCode.getText(lastOperand.node.left),
|
||||
right: unaryOperator + newCode,
|
||||
};
|
||||
}
|
||||
const unaryOperator = lastOperand.node.left.type === utils_1.AST_NODE_TYPES.UnaryExpression
|
||||
? `${lastOperand.node.left.operator} `
|
||||
: '';
|
||||
return {
|
||||
left: unaryOperator + newCode,
|
||||
right: sourceCode.getText(lastOperand.node.right),
|
||||
};
|
||||
})();
|
||||
newCode = `${left} ${operator} ${right}`;
|
||||
}
|
||||
else if (lastOperand.comparisonType === "NotBoolean" /* NullishComparisonType.NotBoolean */) {
|
||||
newCode = `!${newCode}`;
|
||||
}
|
||||
const reportRange = getReportRange(chain, node.range, sourceCode);
|
||||
const fix = fixer => fixer.replaceTextRange(reportRange, newCode);
|
||||
return {
|
||||
loc: {
|
||||
end: sourceCode.getLocFromIndex(reportRange[1]),
|
||||
start: sourceCode.getLocFromIndex(reportRange[0]),
|
||||
},
|
||||
messageId: 'preferOptionalChain',
|
||||
...(0, util_1.getFixOrSuggest)({
|
||||
fixOrSuggest: useSuggestionFixer ? 'suggest' : 'fix',
|
||||
suggestion: {
|
||||
fix,
|
||||
messageId: 'optionalChainSuggest',
|
||||
},
|
||||
}),
|
||||
};
|
||||
function flattenChainExpression(sourceCode, node) {
|
||||
switch (node.type) {
|
||||
case utils_1.AST_NODE_TYPES.ChainExpression:
|
||||
return flattenChainExpression(sourceCode, node.expression);
|
||||
case utils_1.AST_NODE_TYPES.CallExpression: {
|
||||
const argumentsText = (() => {
|
||||
const closingParenToken = (0, util_1.nullThrows)(sourceCode.getLastToken(node), util_1.NullThrowsReasons.MissingToken('closing parenthesis', node.type));
|
||||
const openingParenToken = (0, util_1.nullThrows)(sourceCode.getFirstTokenBetween(node.typeArguments ?? node.callee, closingParenToken, util_1.isOpeningParenToken), util_1.NullThrowsReasons.MissingToken('opening parenthesis', node.type));
|
||||
return sourceCode.text.substring(openingParenToken.range[0], closingParenToken.range[1]);
|
||||
})();
|
||||
const typeArgumentsText = (() => {
|
||||
if (node.typeArguments == null) {
|
||||
return '';
|
||||
}
|
||||
return sourceCode.getText(node.typeArguments);
|
||||
})();
|
||||
return [
|
||||
...flattenChainExpression(sourceCode, node.callee),
|
||||
{
|
||||
nonNull: false,
|
||||
optional: node.optional,
|
||||
// no precedence for this
|
||||
precedence: util_1.OperatorPrecedence.Invalid,
|
||||
requiresDot: false,
|
||||
text: typeArgumentsText + argumentsText,
|
||||
},
|
||||
];
|
||||
}
|
||||
case utils_1.AST_NODE_TYPES.MemberExpression: {
|
||||
const propertyText = sourceCode.getText(node.property);
|
||||
return [
|
||||
...flattenChainExpression(sourceCode, node.object),
|
||||
{
|
||||
nonNull: node.object.type === utils_1.AST_NODE_TYPES.TSNonNullExpression,
|
||||
optional: node.optional,
|
||||
precedence: node.computed
|
||||
? // computed is already wrapped in [] so no need to wrap in () as well
|
||||
util_1.OperatorPrecedence.Invalid
|
||||
: (0, util_1.getOperatorPrecedenceForNode)(node.property),
|
||||
requiresDot: !node.computed,
|
||||
text: node.computed ? `[${propertyText}]` : propertyText,
|
||||
},
|
||||
];
|
||||
}
|
||||
case utils_1.AST_NODE_TYPES.TSNonNullExpression:
|
||||
return flattenChainExpression(sourceCode, node.expression);
|
||||
default:
|
||||
return [
|
||||
{
|
||||
nonNull: false,
|
||||
optional: false,
|
||||
precedence: (0, util_1.getOperatorPrecedenceForNode)(node),
|
||||
requiresDot: false,
|
||||
text: sourceCode.getText(node),
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
function analyzeChain(context, parserServices, options, node, operator, chain) {
|
||||
// need at least 2 operands in a chain for it to be a chain
|
||||
if (chain.length <= 1 ||
|
||||
/* istanbul ignore next -- previous checks make this unreachable, but keep it for exhaustiveness check */
|
||||
operator === '??') {
|
||||
return;
|
||||
}
|
||||
const analyzeOperand = (() => {
|
||||
switch (operator) {
|
||||
case '&&':
|
||||
return analyzeAndChainOperand;
|
||||
case '||':
|
||||
return analyzeOrChainOperand;
|
||||
}
|
||||
})();
|
||||
// Things like x !== null && x !== undefined have two nodes, but they are
|
||||
// one logical unit here, so we'll allow them to be grouped.
|
||||
let subChain = [];
|
||||
const maybeReportThenReset = (newChainSeed) => {
|
||||
if (subChain.length > 1) {
|
||||
const subChainFlat = subChain.flat();
|
||||
(0, checkNullishAndReport_1.checkNullishAndReport)(context, parserServices, options, subChainFlat.slice(0, -1).map(({ node }) => node), getReportDescriptor(context.sourceCode, parserServices, node, operator, options, subChainFlat));
|
||||
}
|
||||
// we've reached the end of a chain of logical expressions
|
||||
// i.e. the current operand doesn't belong to the previous chain.
|
||||
//
|
||||
// we don't want to throw away the current operand otherwise we will skip it
|
||||
// and that can cause us to miss chains. So instead we seed the new chain
|
||||
// with the current operand
|
||||
//
|
||||
// eg this means we can catch cases like:
|
||||
// unrelated != null && foo != null && foo.bar != null;
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ first "chain"
|
||||
// ^^^^^^^^^^^ newChainSeed
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ second chain
|
||||
subChain = newChainSeed ? [newChainSeed] : [];
|
||||
};
|
||||
for (let i = 0; i < chain.length; i += 1) {
|
||||
const lastOperand = subChain.flat().at(-1);
|
||||
const operand = chain[i];
|
||||
const validatedOperands = analyzeOperand(parserServices, operand, i, chain);
|
||||
if (!validatedOperands) {
|
||||
// TODO - #7170
|
||||
// check if the name is a superset/equal - if it is, then it likely
|
||||
// intended to be part of the chain and something we should include in the
|
||||
// report, eg
|
||||
// foo == null || foo.bar;
|
||||
// ^^^^^^^^^^^ valid OR chain
|
||||
// ^^^^^^^ invalid OR chain logical, but still part of
|
||||
// the chain for combination purposes
|
||||
maybeReportThenReset();
|
||||
continue;
|
||||
}
|
||||
// in case multiple operands were consumed - make sure to correctly increment the index
|
||||
i += validatedOperands.length - 1;
|
||||
const currentOperand = validatedOperands[0];
|
||||
if (lastOperand) {
|
||||
const comparisonResult = (0, compareNodes_1.compareNodes)(lastOperand.comparedName,
|
||||
// purposely inspect and push the last operand because the prior operands don't matter
|
||||
// this also means we won't false-positive in cases like
|
||||
// foo !== null && foo !== undefined
|
||||
validatedOperands[validatedOperands.length - 1].comparedName);
|
||||
if (comparisonResult === "Subset" /* NodeComparisonResult.Subset */) {
|
||||
// the operands are comparable, so we can continue searching
|
||||
subChain.push(currentOperand);
|
||||
}
|
||||
else if (comparisonResult === "Invalid" /* NodeComparisonResult.Invalid */) {
|
||||
maybeReportThenReset(validatedOperands);
|
||||
}
|
||||
else {
|
||||
// purposely don't push this case because the node is a no-op and if
|
||||
// we consider it then we might report on things like
|
||||
// foo && foo
|
||||
}
|
||||
}
|
||||
else {
|
||||
subChain.push(currentOperand);
|
||||
}
|
||||
}
|
||||
// check the leftovers
|
||||
maybeReportThenReset();
|
||||
}
|
||||
//# sourceMappingURL=analyzeChain.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
+366
@@ -0,0 +1,366 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
const tsutils = __importStar(require("ts-api-utils"));
|
||||
const ts = __importStar(require("typescript"));
|
||||
const util_1 = require("../util");
|
||||
const getOperatorPrecedence_1 = require("../util/getOperatorPrecedence");
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'return-await',
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Enforce consistent awaiting of returned promises',
|
||||
extendsBaseRule: 'no-return-await',
|
||||
recommended: {
|
||||
strict: ['error-handling-correctness-only'],
|
||||
},
|
||||
requiresTypeChecking: true,
|
||||
},
|
||||
fixable: 'code',
|
||||
// eslint-disable-next-line eslint-plugin/require-meta-has-suggestions -- suggestions are exposed through a helper.
|
||||
hasSuggestions: true,
|
||||
messages: {
|
||||
disallowedPromiseAwait: 'Returning an awaited promise is not allowed in this context.',
|
||||
disallowedPromiseAwaitSuggestion: 'Remove `await` before the expression. Use caution as this may impact control flow.',
|
||||
nonPromiseAwait: 'Returning an awaited value that is not a promise is not allowed.',
|
||||
requiredPromiseAwait: 'Returning an awaited promise is required in this context.',
|
||||
requiredPromiseAwaitSuggestion: 'Add `await` before the expression. Use caution as this may impact control flow.',
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'string',
|
||||
oneOf: [
|
||||
{
|
||||
type: 'string',
|
||||
description: 'Requires that all returned promises be awaited.',
|
||||
enum: ['always'],
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
description: 'In error-handling contexts, the rule enforces that returned promises must be awaited. In ordinary contexts, the rule does not enforce any particular behavior around whether returned promises are awaited.',
|
||||
enum: ['error-handling-correctness-only'],
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
description: 'In error-handling contexts, the rule enforces that returned promises must be awaited. In ordinary contexts, the rule enforces that returned promises _must not_ be awaited.',
|
||||
enum: ['in-try-catch'],
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
description: 'Disallows awaiting any returned promises.',
|
||||
enum: ['never'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultOptions: ['in-try-catch'],
|
||||
create(context, [option]) {
|
||||
const services = (0, util_1.getParserServices)(context);
|
||||
const checker = services.program.getTypeChecker();
|
||||
const scopeInfoStack = [];
|
||||
function enterFunction(node) {
|
||||
scopeInfoStack.push({
|
||||
hasAsync: node.async,
|
||||
owningFunc: node,
|
||||
});
|
||||
}
|
||||
function exitFunction() {
|
||||
scopeInfoStack.pop();
|
||||
}
|
||||
function affectsExplicitResourceManagement(node) {
|
||||
// just need to determine if there is a `using` declaration in scope.
|
||||
let scope = context.sourceCode.getScope(node);
|
||||
const functionScope = scope.variableScope;
|
||||
while (true) {
|
||||
for (const variable of scope.variables) {
|
||||
if (variable.defs.length !== 1) {
|
||||
// This can't be the case for `using` or `await using` since it's
|
||||
// an error to redeclare those more than once in the same scope,
|
||||
// unlike, say, `var` declarations.
|
||||
continue;
|
||||
}
|
||||
const declaration = variable.defs[0];
|
||||
const declaratorNode = declaration.node;
|
||||
const declarationNode = declaratorNode.parent;
|
||||
// if it's a using/await using declaration, and it comes _before_ the
|
||||
// node we're checking, it affects control flow for that node.
|
||||
if (['await using', 'using'].includes(declarationNode.kind) &&
|
||||
declaratorNode.range[1] < node.range[0]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (scope === functionScope) {
|
||||
// We've checked all the relevant scopes
|
||||
break;
|
||||
}
|
||||
// This should always exist, since the rule should only be checking
|
||||
// contexts in which `return` statements are legal, which should always
|
||||
// be inside a function.
|
||||
scope = (0, util_1.nullThrows)(scope.upper, 'Expected parent scope to exist. return-await should only operate on return statements within functions');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Tests whether a node is inside of an explicit error handling context
|
||||
* (try/catch/finally) in a way that throwing an exception will have an
|
||||
* impact on the program's control flow.
|
||||
*/
|
||||
function affectsExplicitErrorHandling(node) {
|
||||
// If an error-handling block is followed by another error-handling block,
|
||||
// control flow is affected by whether promises in it are awaited or not.
|
||||
// Otherwise, we need to check recursively for nested try statements until
|
||||
// we get to the top level of a function or the program. If by then,
|
||||
// there's no offending error-handling blocks, it doesn't affect control
|
||||
// flow.
|
||||
const tryAncestorResult = findContainingTryStatement(node);
|
||||
if (tryAncestorResult == null) {
|
||||
return false;
|
||||
}
|
||||
const { block, tryStatement } = tryAncestorResult;
|
||||
switch (block) {
|
||||
case 'catch':
|
||||
// Exceptions thrown in catch blocks followed by a finally block affect
|
||||
// control flow.
|
||||
if (tryStatement.finallyBlock != null) {
|
||||
return true;
|
||||
}
|
||||
// Otherwise recurse.
|
||||
return affectsExplicitErrorHandling(tryStatement);
|
||||
case 'finally':
|
||||
return affectsExplicitErrorHandling(tryStatement);
|
||||
case 'try':
|
||||
// Try blocks are always followed by either a catch or finally,
|
||||
// so exceptions thrown here always affect control flow.
|
||||
return true;
|
||||
default: {
|
||||
const __never = block;
|
||||
throw new Error(`Unexpected block type: ${String(__never)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* A try _statement_ is the whole thing that encompasses try block,
|
||||
* catch clause, and finally block. This function finds the nearest
|
||||
* enclosing try statement (if present) for a given node, and reports which
|
||||
* part of the try statement the node is in.
|
||||
*/
|
||||
function findContainingTryStatement(node) {
|
||||
let child = node;
|
||||
let ancestor = node.parent;
|
||||
while (ancestor && !ts.isFunctionLike(ancestor)) {
|
||||
if (ts.isTryStatement(ancestor)) {
|
||||
let block;
|
||||
if (child === ancestor.tryBlock) {
|
||||
block = 'try';
|
||||
}
|
||||
else if (child === ancestor.catchClause) {
|
||||
block = 'catch';
|
||||
}
|
||||
else if (child === ancestor.finallyBlock) {
|
||||
block = 'finally';
|
||||
}
|
||||
return {
|
||||
block: (0, util_1.nullThrows)(block, 'Child of a try statement must be a try block, catch clause, or finally block'),
|
||||
tryStatement: ancestor,
|
||||
};
|
||||
}
|
||||
child = ancestor;
|
||||
ancestor = ancestor.parent;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
function removeAwait(fixer, node) {
|
||||
// Should always be an await node; but let's be safe.
|
||||
/* istanbul ignore if */ if (!(0, util_1.isAwaitExpression)(node)) {
|
||||
return null;
|
||||
}
|
||||
const awaitToken = context.sourceCode.getFirstToken(node, util_1.isAwaitKeyword);
|
||||
// Should always be the case; but let's be safe.
|
||||
/* istanbul ignore if */ if (!awaitToken) {
|
||||
return null;
|
||||
}
|
||||
const startAt = awaitToken.range[0];
|
||||
let endAt = awaitToken.range[1];
|
||||
// Also remove any extraneous whitespace after `await`, if there is any.
|
||||
const nextToken = context.sourceCode.getTokenAfter(awaitToken, {
|
||||
includeComments: true,
|
||||
});
|
||||
if (nextToken) {
|
||||
endAt = nextToken.range[0];
|
||||
}
|
||||
return fixer.removeRange([startAt, endAt]);
|
||||
}
|
||||
function insertAwait(fixer, node, isHighPrecendence) {
|
||||
if (isHighPrecendence) {
|
||||
return fixer.insertTextBefore(node, 'await ');
|
||||
}
|
||||
return [
|
||||
fixer.insertTextBefore(node, 'await ('),
|
||||
fixer.insertTextAfter(node, ')'),
|
||||
];
|
||||
}
|
||||
function isHigherPrecedenceThanAwait(node) {
|
||||
const operator = ts.isBinaryExpression(node)
|
||||
? node.operatorToken.kind
|
||||
: ts.SyntaxKind.Unknown;
|
||||
const nodePrecedence = (0, getOperatorPrecedence_1.getOperatorPrecedence)(node.kind, operator);
|
||||
const awaitPrecedence = (0, getOperatorPrecedence_1.getOperatorPrecedence)(ts.SyntaxKind.AwaitExpression, ts.SyntaxKind.Unknown);
|
||||
return nodePrecedence > awaitPrecedence;
|
||||
}
|
||||
function test(node, expression) {
|
||||
let child;
|
||||
const isAwait = ts.isAwaitExpression(expression);
|
||||
if (isAwait) {
|
||||
child = expression.getChildAt(1);
|
||||
}
|
||||
else {
|
||||
child = expression;
|
||||
}
|
||||
const type = checker.getTypeAtLocation(child);
|
||||
const isThenable = tsutils.isThenableType(checker, expression, type);
|
||||
// handle awaited _non_thenables
|
||||
if (!isThenable) {
|
||||
if (isAwait) {
|
||||
// any/unknown could be thenable; do not enforce whether they are `await`ed.
|
||||
if ((0, util_1.isTypeAnyType)(type) || (0, util_1.isTypeUnknownType)(type)) {
|
||||
return;
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'nonPromiseAwait',
|
||||
fix: fixer => removeAwait(fixer, node),
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
// At this point it's definitely a thenable.
|
||||
const affectsErrorHandling = affectsExplicitErrorHandling(expression) ||
|
||||
affectsExplicitResourceManagement(node);
|
||||
const useAutoFix = !affectsErrorHandling;
|
||||
const ruleConfiguration = getConfiguration(option);
|
||||
const shouldAwaitInCurrentContext = affectsErrorHandling
|
||||
? ruleConfiguration.errorHandlingContext
|
||||
: ruleConfiguration.ordinaryContext;
|
||||
switch (shouldAwaitInCurrentContext) {
|
||||
case 'await':
|
||||
if (!isAwait) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'requiredPromiseAwait',
|
||||
...(0, util_1.getFixOrSuggest)({
|
||||
fixOrSuggest: useAutoFix ? 'fix' : 'suggest',
|
||||
suggestion: {
|
||||
messageId: 'requiredPromiseAwaitSuggestion',
|
||||
fix: fixer => insertAwait(fixer, node, isHigherPrecedenceThanAwait(expression)),
|
||||
},
|
||||
}),
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "don't-care":
|
||||
break;
|
||||
case 'no-await':
|
||||
if (isAwait) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'disallowedPromiseAwait',
|
||||
...(0, util_1.getFixOrSuggest)({
|
||||
fixOrSuggest: useAutoFix ? 'fix' : 'suggest',
|
||||
suggestion: {
|
||||
messageId: 'disallowedPromiseAwaitSuggestion',
|
||||
fix: fixer => removeAwait(fixer, node),
|
||||
},
|
||||
}),
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
function findPossiblyReturnedNodes(node) {
|
||||
if (node.type === utils_1.AST_NODE_TYPES.ConditionalExpression) {
|
||||
return [
|
||||
...findPossiblyReturnedNodes(node.alternate),
|
||||
...findPossiblyReturnedNodes(node.consequent),
|
||||
];
|
||||
}
|
||||
return [node];
|
||||
}
|
||||
return {
|
||||
ArrowFunctionExpression: enterFunction,
|
||||
'ArrowFunctionExpression:exit': exitFunction,
|
||||
FunctionDeclaration: enterFunction,
|
||||
'FunctionDeclaration:exit': exitFunction,
|
||||
FunctionExpression: enterFunction,
|
||||
'FunctionExpression:exit': exitFunction,
|
||||
// executes after less specific handler, so exitFunction is called
|
||||
'ArrowFunctionExpression[async = true]:exit'(node) {
|
||||
if (node.body.type !== utils_1.AST_NODE_TYPES.BlockStatement) {
|
||||
findPossiblyReturnedNodes(node.body).forEach(node => {
|
||||
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
|
||||
test(node, tsNode);
|
||||
});
|
||||
}
|
||||
},
|
||||
ReturnStatement(node) {
|
||||
const scopeInfo = scopeInfoStack.at(-1);
|
||||
if (!scopeInfo?.hasAsync || !node.argument) {
|
||||
return;
|
||||
}
|
||||
findPossiblyReturnedNodes(node.argument).forEach(node => {
|
||||
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
|
||||
test(node, tsNode);
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
function getConfiguration(option) {
|
||||
switch (option) {
|
||||
case 'always':
|
||||
return {
|
||||
errorHandlingContext: 'await',
|
||||
ordinaryContext: 'await',
|
||||
};
|
||||
case 'error-handling-correctness-only':
|
||||
return {
|
||||
errorHandlingContext: 'await',
|
||||
ordinaryContext: "don't-care",
|
||||
};
|
||||
case 'in-try-catch':
|
||||
return {
|
||||
errorHandlingContext: 'await',
|
||||
ordinaryContext: 'no-await',
|
||||
};
|
||||
case 'never':
|
||||
return {
|
||||
errorHandlingContext: 'no-await',
|
||||
ordinaryContext: 'no-await',
|
||||
};
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=return-await.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+259
@@ -0,0 +1,259 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tsutils = __importStar(require("ts-api-utils"));
|
||||
const ts = __importStar(require("typescript"));
|
||||
const util_1 = require("../util");
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'switch-exhaustiveness-check',
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'Require switch-case statements to be exhaustive',
|
||||
requiresTypeChecking: true,
|
||||
},
|
||||
hasSuggestions: true,
|
||||
messages: {
|
||||
addMissingCases: 'Add branches for missing cases.',
|
||||
dangerousDefaultCase: 'The switch statement is exhaustive, so the default case is unnecessary.',
|
||||
switchIsNotExhaustive: 'Switch is not exhaustive. Cases not matched: {{missingBranches}}',
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
allowDefaultCaseForExhaustiveSwitch: {
|
||||
type: 'boolean',
|
||||
description: `If 'true', allow 'default' cases on switch statements with exhaustive cases.`,
|
||||
},
|
||||
considerDefaultExhaustiveForUnions: {
|
||||
type: 'boolean',
|
||||
description: `If 'true', the 'default' clause is used to determine whether the switch statement is exhaustive for union type`,
|
||||
},
|
||||
requireDefaultForNonUnion: {
|
||||
type: 'boolean',
|
||||
description: `If 'true', require a 'default' clause for switches on non-union types.`,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultOptions: [
|
||||
{
|
||||
allowDefaultCaseForExhaustiveSwitch: true,
|
||||
considerDefaultExhaustiveForUnions: false,
|
||||
requireDefaultForNonUnion: false,
|
||||
},
|
||||
],
|
||||
create(context, [{ allowDefaultCaseForExhaustiveSwitch, considerDefaultExhaustiveForUnions, requireDefaultForNonUnion, },]) {
|
||||
const services = (0, util_1.getParserServices)(context);
|
||||
const checker = services.program.getTypeChecker();
|
||||
const compilerOptions = services.program.getCompilerOptions();
|
||||
function getSwitchMetadata(node) {
|
||||
const defaultCase = node.cases.find(switchCase => switchCase.test == null);
|
||||
const discriminantType = (0, util_1.getConstrainedTypeAtLocation)(services, node.discriminant);
|
||||
const symbolName = discriminantType.getSymbol()?.escapedName;
|
||||
const containsNonLiteralType = doesTypeContainNonLiteralType(discriminantType);
|
||||
const caseTypes = new Set();
|
||||
for (const switchCase of node.cases) {
|
||||
// If the `test` property of the switch case is `null`, then we are on a
|
||||
// `default` case.
|
||||
if (switchCase.test == null) {
|
||||
continue;
|
||||
}
|
||||
const caseType = (0, util_1.getConstrainedTypeAtLocation)(services, switchCase.test);
|
||||
caseTypes.add(caseType);
|
||||
}
|
||||
const missingLiteralBranchTypes = [];
|
||||
for (const unionPart of tsutils.unionTypeParts(discriminantType)) {
|
||||
for (const intersectionPart of tsutils.intersectionTypeParts(unionPart)) {
|
||||
if (caseTypes.has(intersectionPart) ||
|
||||
!isTypeLiteralLikeType(intersectionPart)) {
|
||||
continue;
|
||||
}
|
||||
// "missing", "optional" and "undefined" types are different runtime objects,
|
||||
// but all of them have TypeFlags.Undefined type flag
|
||||
if ([...caseTypes].some(tsutils.isIntrinsicUndefinedType) &&
|
||||
tsutils.isIntrinsicUndefinedType(intersectionPart)) {
|
||||
continue;
|
||||
}
|
||||
missingLiteralBranchTypes.push(intersectionPart);
|
||||
}
|
||||
}
|
||||
return {
|
||||
containsNonLiteralType,
|
||||
defaultCase,
|
||||
missingLiteralBranchTypes,
|
||||
symbolName,
|
||||
};
|
||||
}
|
||||
function checkSwitchExhaustive(node, switchMetadata) {
|
||||
const { defaultCase, missingLiteralBranchTypes, symbolName } = switchMetadata;
|
||||
// If considerDefaultExhaustiveForUnions is enabled, the presence of a default case
|
||||
// always makes the switch exhaustive.
|
||||
if (considerDefaultExhaustiveForUnions && defaultCase != null) {
|
||||
return;
|
||||
}
|
||||
if (missingLiteralBranchTypes.length > 0) {
|
||||
context.report({
|
||||
node: node.discriminant,
|
||||
messageId: 'switchIsNotExhaustive',
|
||||
data: {
|
||||
missingBranches: missingLiteralBranchTypes
|
||||
.map(missingType => tsutils.isTypeFlagSet(missingType, ts.TypeFlags.ESSymbolLike)
|
||||
? `typeof ${missingType.getSymbol()?.escapedName}`
|
||||
: checker.typeToString(missingType))
|
||||
.join(' | '),
|
||||
},
|
||||
suggest: [
|
||||
{
|
||||
messageId: 'addMissingCases',
|
||||
fix(fixer) {
|
||||
return fixSwitch(fixer, node, missingLiteralBranchTypes, symbolName?.toString());
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
function fixSwitch(fixer, node, missingBranchTypes, // null means default branch
|
||||
symbolName) {
|
||||
const lastCase = node.cases.length > 0 ? node.cases[node.cases.length - 1] : null;
|
||||
const defaultCase = node.cases.find(caseEl => caseEl.test == null);
|
||||
const caseIndent = lastCase
|
||||
? ' '.repeat(lastCase.loc.start.column)
|
||||
: // If there are no cases, use indentation of the switch statement and
|
||||
// leave it to the user to format it correctly.
|
||||
' '.repeat(node.loc.start.column);
|
||||
const missingCases = [];
|
||||
for (const missingBranchType of missingBranchTypes) {
|
||||
if (missingBranchType == null) {
|
||||
missingCases.push(`default: { throw new Error('default case') }`);
|
||||
continue;
|
||||
}
|
||||
const missingBranchName = missingBranchType.getSymbol()?.escapedName;
|
||||
let caseTest = tsutils.isTypeFlagSet(missingBranchType, ts.TypeFlags.ESSymbolLike)
|
||||
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
missingBranchName
|
||||
: checker.typeToString(missingBranchType);
|
||||
if (symbolName &&
|
||||
(missingBranchName || missingBranchName === '') &&
|
||||
(0, util_1.requiresQuoting)(missingBranchName.toString(), compilerOptions.target)) {
|
||||
const escapedBranchName = missingBranchName
|
||||
.replaceAll("'", "\\'")
|
||||
.replaceAll('\n', '\\n')
|
||||
.replaceAll('\r', '\\r');
|
||||
caseTest = `${symbolName}['${escapedBranchName}']`;
|
||||
}
|
||||
missingCases.push(`case ${caseTest}: { throw new Error('Not implemented yet: ${caseTest
|
||||
.replaceAll('\\', '\\\\')
|
||||
.replaceAll("'", "\\'")} case') }`);
|
||||
}
|
||||
const fixString = missingCases
|
||||
.map(code => `${caseIndent}${code}`)
|
||||
.join('\n');
|
||||
if (lastCase) {
|
||||
if (defaultCase) {
|
||||
const beforeFixString = missingCases
|
||||
.map(code => `${code}\n${caseIndent}`)
|
||||
.join('');
|
||||
return fixer.insertTextBefore(defaultCase, beforeFixString);
|
||||
}
|
||||
return fixer.insertTextAfter(lastCase, `\n${fixString}`);
|
||||
}
|
||||
// There were no existing cases.
|
||||
const openingBrace = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(node.discriminant, util_1.isOpeningBraceToken), util_1.NullThrowsReasons.MissingToken('{', 'discriminant'));
|
||||
const closingBrace = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(node.discriminant, util_1.isClosingBraceToken), util_1.NullThrowsReasons.MissingToken('}', 'discriminant'));
|
||||
return fixer.replaceTextRange([openingBrace.range[0], closingBrace.range[1]], ['{', fixString, `${caseIndent}}`].join('\n'));
|
||||
}
|
||||
function checkSwitchUnnecessaryDefaultCase(switchMetadata) {
|
||||
if (allowDefaultCaseForExhaustiveSwitch) {
|
||||
return;
|
||||
}
|
||||
const { containsNonLiteralType, defaultCase, missingLiteralBranchTypes } = switchMetadata;
|
||||
if (missingLiteralBranchTypes.length === 0 &&
|
||||
defaultCase !== undefined &&
|
||||
!containsNonLiteralType) {
|
||||
context.report({
|
||||
node: defaultCase,
|
||||
messageId: 'dangerousDefaultCase',
|
||||
});
|
||||
}
|
||||
}
|
||||
function checkSwitchNoUnionDefaultCase(node, switchMetadata) {
|
||||
if (!requireDefaultForNonUnion) {
|
||||
return;
|
||||
}
|
||||
const { containsNonLiteralType, defaultCase } = switchMetadata;
|
||||
if (containsNonLiteralType && defaultCase === undefined) {
|
||||
context.report({
|
||||
node: node.discriminant,
|
||||
messageId: 'switchIsNotExhaustive',
|
||||
data: { missingBranches: 'default' },
|
||||
suggest: [
|
||||
{
|
||||
messageId: 'addMissingCases',
|
||||
fix(fixer) {
|
||||
return fixSwitch(fixer, node, [null]);
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
return {
|
||||
SwitchStatement(node) {
|
||||
const switchMetadata = getSwitchMetadata(node);
|
||||
checkSwitchExhaustive(node, switchMetadata);
|
||||
checkSwitchUnnecessaryDefaultCase(switchMetadata);
|
||||
checkSwitchNoUnionDefaultCase(node, switchMetadata);
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
function isTypeLiteralLikeType(type) {
|
||||
return tsutils.isTypeFlagSet(type, ts.TypeFlags.Literal |
|
||||
ts.TypeFlags.Undefined |
|
||||
ts.TypeFlags.Null |
|
||||
ts.TypeFlags.UniqueESSymbol);
|
||||
}
|
||||
/**
|
||||
* For example:
|
||||
*
|
||||
* - `"foo" | "bar"` is a type with all literal types.
|
||||
* - `"foo" | number` is a type that contains non-literal types.
|
||||
* - `"foo" & { bar: 1 }` is a type that contains non-literal types.
|
||||
*
|
||||
* Default cases are never superfluous in switches with non-literal types.
|
||||
*/
|
||||
function doesTypeContainNonLiteralType(type) {
|
||||
return tsutils
|
||||
.unionTypeParts(type)
|
||||
.some(type => tsutils
|
||||
.intersectionTypeParts(type)
|
||||
.every(subType => !isTypeLiteralLikeType(subType)));
|
||||
}
|
||||
//# sourceMappingURL=switch-exhaustiveness-check.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
+14
@@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getFixOrSuggest = getFixOrSuggest;
|
||||
function getFixOrSuggest({ fixOrSuggest, suggestion, }) {
|
||||
switch (fixOrSuggest) {
|
||||
case 'fix':
|
||||
return { fix: suggestion.fix };
|
||||
case 'none':
|
||||
return undefined;
|
||||
case 'suggest':
|
||||
return { suggest: [suggestion] };
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=getFixOrSuggest.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"getFixOrSuggest.js","sourceRoot":"","sources":["../../src/util/getFixOrSuggest.ts"],"names":[],"mappings":";;AAEA,0CAkBC;AAlBD,SAAgB,eAAe,CAA2B,EACxD,YAAY,EACZ,UAAU,GAIX;IAIC,QAAQ,YAAY,EAAE,CAAC;QACrB,KAAK,KAAK;YACR,OAAO,EAAE,GAAG,EAAE,UAAU,CAAC,GAAG,EAAE,CAAC;QACjC,KAAK,MAAM;YACT,OAAO,SAAS,CAAC;QACnB,KAAK,SAAS;YACZ,OAAO,EAAE,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;IACrC,CAAC;AACH,CAAC"}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getParentFunctionNode = getParentFunctionNode;
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
function getParentFunctionNode(node) {
|
||||
let current = node.parent;
|
||||
while (current) {
|
||||
if (current.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
|
||||
current.type === utils_1.AST_NODE_TYPES.FunctionDeclaration ||
|
||||
current.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
|
||||
return current;
|
||||
}
|
||||
current = current.parent;
|
||||
}
|
||||
// this shouldn't happen in correct code, but someone may attempt to parse bad code
|
||||
// the parser won't error, so we shouldn't throw here
|
||||
/* istanbul ignore next */ return null;
|
||||
}
|
||||
//# sourceMappingURL=getParentFunctionNode.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"getParentFunctionNode.js","sourceRoot":"","sources":["../../src/util/getParentFunctionNode.ts"],"names":[],"mappings":";;AAIA,sDAuBC;AAzBD,oDAA0D;AAE1D,SAAgB,qBAAqB,CACnC,IAAmB;IAMnB,IAAI,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;IAC1B,OAAO,OAAO,EAAE,CAAC;QACf,IACE,OAAO,CAAC,IAAI,KAAK,sBAAc,CAAC,uBAAuB;YACvD,OAAO,CAAC,IAAI,KAAK,sBAAc,CAAC,mBAAmB;YACnD,OAAO,CAAC,IAAI,KAAK,sBAAc,CAAC,kBAAkB,EAClD,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED,mFAAmF;IACnF,qDAAqD;IACrD,0BAA0B,CAAC,OAAO,IAAI,CAAC;AACzC,CAAC"}
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
---
|
||||
description: 'Disallow awaiting a value that is not a Thenable.'
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
> 🛑 This file is source code, not the primary documentation location! 🛑
|
||||
>
|
||||
> See **https://typescript-eslint.io/rules/await-thenable** for documentation.
|
||||
|
||||
A "Thenable" value is an object which has a `then` method, such as a Promise.
|
||||
The [`await` keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await) is generally used to retrieve the result of calling a Thenable's `then` method.
|
||||
|
||||
If the `await` keyword is used on a value that is not a Thenable, the value is directly resolved, but will still pause execution until the next microtask.
|
||||
While doing so is valid JavaScript, it is often a programmer error, such as forgetting to add parenthesis to call a function that returns a Promise.
|
||||
|
||||
## Examples
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="❌ Incorrect">
|
||||
|
||||
```ts
|
||||
await 'value';
|
||||
|
||||
const createValue = () => 'value';
|
||||
await createValue();
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="✅ Correct">
|
||||
|
||||
```ts
|
||||
await Promise.resolve('value');
|
||||
|
||||
const createValue = async () => 'value';
|
||||
await createValue();
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Async Iteration (`for await...of` Loops)
|
||||
|
||||
This rule also inspects [`for await...of` statements](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of), and reports if the value being iterated over is not async-iterable.
|
||||
|
||||
:::info[Why does the rule report on `for await...of` loops used on an array of Promises?]
|
||||
|
||||
While `for await...of` can be used with synchronous iterables, and it will await each promise produced by the iterable, it is inadvisable to do so.
|
||||
There are some tiny nuances that you may want to consider.
|
||||
|
||||
The biggest difference between using `for await...of` and using `for...of` (apart from awaiting each result yourself) is error handling.
|
||||
When an error occurs within the loop body, `for await...of` does _not_ close the original sync iterable, while `for...of` does.
|
||||
For detailed examples of this, see the [MDN documentation on using `for await...of` with sync-iterables](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of#iterating_over_sync_iterables_and_generators).
|
||||
|
||||
Also consider whether you need sequential awaiting at all. Using `for await...of` may obscure potential opportunities for concurrent processing, such as those reported by [`no-await-in-loop`](https://eslint.org/docs/latest/rules/no-await-in-loop). Consider instead using one of the [promise concurrency methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#promise_concurrency) for better performance.
|
||||
|
||||
:::
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="❌ Incorrect">
|
||||
|
||||
```ts
|
||||
async function syncIterable() {
|
||||
const arrayOfValues = [1, 2, 3];
|
||||
for await (const value of arrayOfValues) {
|
||||
console.log(value);
|
||||
}
|
||||
}
|
||||
|
||||
async function syncIterableOfPromises() {
|
||||
const arrayOfPromises = [
|
||||
Promise.resolve(1),
|
||||
Promise.resolve(2),
|
||||
Promise.resolve(3),
|
||||
];
|
||||
for await (const promisedValue of arrayOfPromises) {
|
||||
console.log(promisedValue);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="✅ Correct">
|
||||
|
||||
```ts
|
||||
async function syncIterable() {
|
||||
const arrayOfValues = [1, 2, 3];
|
||||
for (const value of arrayOfValues) {
|
||||
console.log(value);
|
||||
}
|
||||
}
|
||||
|
||||
async function syncIterableOfPromises() {
|
||||
const arrayOfPromises = [
|
||||
Promise.resolve(1),
|
||||
Promise.resolve(2),
|
||||
Promise.resolve(3),
|
||||
];
|
||||
for (const promisedValue of await Promise.all(arrayOfPromises)) {
|
||||
console.log(promisedValue);
|
||||
}
|
||||
}
|
||||
|
||||
async function validUseOfForAwaitOnAsyncIterable() {
|
||||
async function* yieldThingsAsynchronously() {
|
||||
yield 1;
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
yield 2;
|
||||
}
|
||||
|
||||
for await (const promisedValue of yieldThingsAsynchronously()) {
|
||||
console.log(promisedValue);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Explicit Resource Management (`await using` Statements)
|
||||
|
||||
This rule also inspects [`await using` statements](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#using-declarations-and-explicit-resource-management).
|
||||
If the disposable being used is not async-disposable, an `await using` statement is unnecessary.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="❌ Incorrect">
|
||||
|
||||
```ts
|
||||
function makeSyncDisposable(): Disposable {
|
||||
return {
|
||||
[Symbol.dispose](): void {
|
||||
// Dispose of the resource
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async function shouldNotAwait() {
|
||||
await using resource = makeSyncDisposable();
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="✅ Correct">
|
||||
|
||||
```ts
|
||||
function makeSyncDisposable(): Disposable {
|
||||
return {
|
||||
[Symbol.dispose](): void {
|
||||
// Dispose of the resource
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async function shouldNotAwait() {
|
||||
using resource = makeSyncDisposable();
|
||||
}
|
||||
|
||||
function makeAsyncDisposable(): AsyncDisposable {
|
||||
return {
|
||||
async [Symbol.asyncDispose](): Promise<void> {
|
||||
// Dispose of the resource asynchronously
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async function shouldAwait() {
|
||||
await using resource = makeAsyncDisposable();
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## When Not To Use It
|
||||
|
||||
If you want to allow code to `await` non-Promise values.
|
||||
For example, if your framework is in transition from one style of asynchronous code to another, it may be useful to include `await`s unnecessarily.
|
||||
This is generally not preferred but can sometimes be useful for visual consistency.
|
||||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule.
|
||||
Generated
Vendored
+154
@@ -0,0 +1,154 @@
|
||||
---
|
||||
description: 'Require expressions of type void to appear in statement position.'
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
> 🛑 This file is source code, not the primary documentation location! 🛑
|
||||
>
|
||||
> See **https://typescript-eslint.io/rules/no-confusing-void-expression** for documentation.
|
||||
|
||||
`void` in TypeScript refers to a function return that is meant to be ignored.
|
||||
Attempting to use a `void`-typed value, such as storing the result of a called function in a variable, is often a sign of a programmer error.
|
||||
`void` can also be misleading for other developers even if used correctly.
|
||||
|
||||
This rule prevents `void` type expressions from being used in misleading locations such as being assigned to a variable, provided as a function argument, or returned from a function.
|
||||
|
||||
## Examples
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="❌ Incorrect">
|
||||
|
||||
```ts
|
||||
// somebody forgot that `alert` doesn't return anything
|
||||
const response = alert('Are you sure?');
|
||||
console.log(alert('Are you sure?'));
|
||||
|
||||
// it's not obvious whether the chained promise will contain the response (fixable)
|
||||
promise.then(value => window.postMessage(value));
|
||||
|
||||
// it looks like we are returning the result of `console.error` (fixable)
|
||||
function doSomething() {
|
||||
if (!somethingToDo) {
|
||||
return console.error('Nothing to do!');
|
||||
}
|
||||
|
||||
console.log('Doing a thing...');
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="✅ Correct">
|
||||
|
||||
```ts
|
||||
// just a regular void function in a statement position
|
||||
alert('Hello, world!');
|
||||
|
||||
// this function returns a boolean value so it's ok
|
||||
const response = confirm('Are you sure?');
|
||||
console.log(confirm('Are you sure?'));
|
||||
|
||||
// now it's obvious that `postMessage` doesn't return any response
|
||||
promise.then(value => {
|
||||
window.postMessage(value);
|
||||
});
|
||||
|
||||
// now it's explicit that we want to log the error and return early
|
||||
function doSomething() {
|
||||
if (!somethingToDo) {
|
||||
console.error('Nothing to do!');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Doing a thing...');
|
||||
}
|
||||
|
||||
// using logical expressions for their side effects is fine
|
||||
cond && console.log('true');
|
||||
cond || console.error('false');
|
||||
cond ? console.log('true') : console.error('false');
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Options
|
||||
|
||||
### `ignoreArrowShorthand`
|
||||
|
||||
{/* insert option description */}
|
||||
|
||||
Whether to ignore "shorthand" `() =>` arrow functions: those without `{ ... }` braces.
|
||||
|
||||
It might be undesirable to wrap every arrow function shorthand expression.
|
||||
Especially when using the Prettier formatter, which spreads such code across 3 lines instead of 1.
|
||||
|
||||
Examples of additional **correct** code with this option enabled:
|
||||
|
||||
```ts option='{ "ignoreArrowShorthand": true }' showPlaygroundButton
|
||||
promise.then(value => window.postMessage(value));
|
||||
```
|
||||
|
||||
### `ignoreVoidOperator`
|
||||
|
||||
{/* insert option description */}
|
||||
|
||||
Whether to ignore returns that start with the `void` operator.
|
||||
|
||||
It might be preferable to only use some distinct syntax
|
||||
to explicitly mark the confusing but valid usage of void expressions.
|
||||
This option allows void expressions which are explicitly wrapped in the `void` operator.
|
||||
This can help avoid confusion among other developers as long as they are made aware of this code style.
|
||||
|
||||
This option also changes the automatic fixes for common cases to use the `void` operator.
|
||||
It also enables a suggestion fix to wrap the void expression with `void` operator for every problem reported.
|
||||
|
||||
Examples of additional **correct** code with this option enabled:
|
||||
|
||||
```ts option='{ "ignoreVoidOperator": true }' showPlaygroundButton
|
||||
// now it's obvious that we don't expect any response
|
||||
promise.then(value => void window.postMessage(value));
|
||||
|
||||
// now it's explicit that we don't want to return anything
|
||||
function doSomething() {
|
||||
if (!somethingToDo) {
|
||||
return void console.error('Nothing to do!');
|
||||
}
|
||||
|
||||
console.log('Doing a thing...');
|
||||
}
|
||||
|
||||
// we are sure that we want to always log `undefined`
|
||||
console.log(void alert('Hello, world!'));
|
||||
```
|
||||
|
||||
### `ignoreVoidReturningFunctions`
|
||||
|
||||
{/* insert option description */}
|
||||
|
||||
Whether to ignore returns from functions with `void` return types when inside a function with a `void` return type.
|
||||
|
||||
Some projects prefer allowing functions that explicitly return `void` to return `void` expressions. Doing so allows more writing more succinct functions.
|
||||
|
||||
:::note
|
||||
This is technically risky as the `void`-returning function might actually be returning a value not seen by the type system.
|
||||
:::
|
||||
|
||||
```ts option='{ "ignoreVoidReturningFunctions": true }' showPlaygroundButton
|
||||
function foo(): void {
|
||||
return console.log();
|
||||
}
|
||||
|
||||
function onError(callback: () => void): void {
|
||||
callback();
|
||||
}
|
||||
|
||||
onError(() => console.log('oops'));
|
||||
```
|
||||
|
||||
## When Not To Use It
|
||||
|
||||
The return type of a function can be inspected by going to its definition or hovering over it in an IDE.
|
||||
If you don't care about being explicit about the void type in actual code then don't use this rule.
|
||||
Also, if you strongly prefer a concise coding style more strongly than any fear of `void`-related bugs then you can avoid this rule.
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
---
|
||||
description: 'Disallow throwing non-`Error` values as exceptions.'
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
> 🛑 This file is source code, not the primary documentation location! 🛑
|
||||
>
|
||||
> See **https://typescript-eslint.io/rules/only-throw-error** for documentation.
|
||||
|
||||
It is considered good practice to only `throw` the `Error` object itself or an object using the `Error` object as base objects for user-defined exceptions.
|
||||
The fundamental benefit of `Error` objects is that they automatically keep track of where they were built and originated.
|
||||
|
||||
This rule restricts what can be thrown as an exception.
|
||||
|
||||
:::info[Migration from `no-throw-literal`]
|
||||
|
||||
This rule was formerly known as `no-throw-literal`.
|
||||
The new name is a drop-in replacement with identical functionality.
|
||||
|
||||
:::
|
||||
|
||||
## Examples
|
||||
|
||||
This rule is aimed at maintaining consistency when throwing exception by disallowing to throw literals and other expressions which cannot possibly be an `Error` object.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="❌ Incorrect">
|
||||
|
||||
```ts
|
||||
throw 'error';
|
||||
|
||||
throw 0;
|
||||
|
||||
throw undefined;
|
||||
|
||||
throw null;
|
||||
|
||||
const err = new Error();
|
||||
throw 'an ' + err;
|
||||
|
||||
const err = new Error();
|
||||
throw `${err}`;
|
||||
|
||||
const err = '';
|
||||
throw err;
|
||||
|
||||
function getError() {
|
||||
return '';
|
||||
}
|
||||
throw getError();
|
||||
|
||||
const foo = {
|
||||
bar: '',
|
||||
};
|
||||
throw foo.bar;
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="✅ Correct">
|
||||
|
||||
```ts
|
||||
throw new Error();
|
||||
|
||||
throw new Error('error');
|
||||
|
||||
const e = new Error('error');
|
||||
throw e;
|
||||
|
||||
try {
|
||||
throw new Error('error');
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
const err = new Error();
|
||||
throw err;
|
||||
|
||||
function getError() {
|
||||
return new Error();
|
||||
}
|
||||
throw getError();
|
||||
|
||||
const foo = {
|
||||
bar: new Error(),
|
||||
};
|
||||
throw foo.bar;
|
||||
|
||||
class CustomError extends Error {
|
||||
// ...
|
||||
}
|
||||
throw new CustomError();
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Options
|
||||
|
||||
This rule adds the following options:
|
||||
|
||||
```ts
|
||||
interface Options {
|
||||
/**
|
||||
* Type specifiers that can be thrown.
|
||||
*/
|
||||
allow?: (
|
||||
| {
|
||||
from: 'file';
|
||||
name: [string, ...string[]] | string;
|
||||
path?: string;
|
||||
}
|
||||
| {
|
||||
from: 'lib';
|
||||
name: [string, ...string[]] | string;
|
||||
}
|
||||
| {
|
||||
from: 'package';
|
||||
name: [string, ...string[]] | string;
|
||||
package: string;
|
||||
}
|
||||
| string
|
||||
)[];
|
||||
|
||||
/**
|
||||
* Whether to always allow throwing values typed as `any`.
|
||||
*/
|
||||
allowThrowingAny?: boolean;
|
||||
|
||||
/**
|
||||
* Whether to always allow throwing values typed as `unknown`.
|
||||
*/
|
||||
allowThrowingUnknown?: boolean;
|
||||
}
|
||||
|
||||
const defaultOptions: Options = {
|
||||
allow: [],
|
||||
allowThrowingAny: true,
|
||||
allowThrowingUnknown: true,
|
||||
};
|
||||
```
|
||||
|
||||
{/* Intentionally Omitted: When Not To Use It */}
|
||||
Generated
Vendored
+222
@@ -0,0 +1,222 @@
|
||||
---
|
||||
description: 'Enforce using the nullish coalescing operator instead of logical assignments or chaining.'
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
> 🛑 This file is source code, not the primary documentation location! 🛑
|
||||
>
|
||||
> See **https://typescript-eslint.io/rules/prefer-nullish-coalescing** for documentation.
|
||||
|
||||
The `??` nullish coalescing runtime operator allows providing a default value when dealing with `null` or `undefined`.
|
||||
Because the nullish coalescing operator _only_ coalesces when the original value is `null` or `undefined`, it is much safer than relying upon logical OR operator chaining `||`, which coalesces on any _falsy_ value.
|
||||
|
||||
This rule reports when you may consider replacing:
|
||||
|
||||
- An `||` operator with `??`
|
||||
- An `||=` operator with `??=`
|
||||
|
||||
:::caution
|
||||
This rule will not work as expected if [`strictNullChecks`](https://www.typescriptlang.org/tsconfig#strictNullChecks) is not enabled.
|
||||
:::
|
||||
|
||||
## Options
|
||||
|
||||
### `ignoreTernaryTests`
|
||||
|
||||
{/* insert option description */}
|
||||
|
||||
Incorrect code for `ignoreTernaryTests: false`, and correct code for `ignoreTernaryTests: true`:
|
||||
|
||||
```ts option='{ "ignoreTernaryTests": false }' showPlaygroundButton
|
||||
const foo: any = 'bar';
|
||||
foo !== undefined && foo !== null ? foo : 'a string';
|
||||
foo === undefined || foo === null ? 'a string' : foo;
|
||||
foo == undefined ? 'a string' : foo;
|
||||
foo == null ? 'a string' : foo;
|
||||
|
||||
const foo: string | undefined = 'bar';
|
||||
foo !== undefined ? foo : 'a string';
|
||||
foo === undefined ? 'a string' : foo;
|
||||
|
||||
const foo: string | null = 'bar';
|
||||
foo !== null ? foo : 'a string';
|
||||
foo === null ? 'a string' : foo;
|
||||
```
|
||||
|
||||
Correct code for `ignoreTernaryTests: false`:
|
||||
|
||||
```ts option='{ "ignoreTernaryTests": false }' showPlaygroundButton
|
||||
const foo: any = 'bar';
|
||||
foo ?? 'a string';
|
||||
foo ?? 'a string';
|
||||
foo ?? 'a string';
|
||||
foo ?? 'a string';
|
||||
|
||||
const foo: string | undefined = 'bar';
|
||||
foo ?? 'a string';
|
||||
foo ?? 'a string';
|
||||
|
||||
const foo: string | null = 'bar';
|
||||
foo ?? 'a string';
|
||||
foo ?? 'a string';
|
||||
```
|
||||
|
||||
### `ignoreConditionalTests`
|
||||
|
||||
{/* insert option description */}
|
||||
|
||||
Generally expressions within conditional tests intentionally use the falsy fallthrough behavior of the logical or operator, meaning that fixing the operator to the nullish coalesce operator could cause bugs.
|
||||
|
||||
If you're looking to enforce stricter conditional tests, you should consider using the `strict-boolean-expressions` rule.
|
||||
|
||||
Incorrect code for `ignoreConditionalTests: false`, and correct code for `ignoreConditionalTests: true`:
|
||||
|
||||
```ts option='{ "ignoreConditionalTests": false }' showPlaygroundButton
|
||||
declare const a: string | null;
|
||||
declare const b: string | null;
|
||||
|
||||
if (a || b) {
|
||||
}
|
||||
if ((a ||= b)) {
|
||||
}
|
||||
while (a || b) {}
|
||||
while ((a ||= b)) {}
|
||||
do {} while (a || b);
|
||||
for (let i = 0; a || b; i += 1) {}
|
||||
a || b ? true : false;
|
||||
```
|
||||
|
||||
Correct code for `ignoreConditionalTests: false`:
|
||||
|
||||
```ts option='{ "ignoreConditionalTests": false }' showPlaygroundButton
|
||||
declare const a: string | null;
|
||||
declare const b: string | null;
|
||||
|
||||
if (a ?? b) {
|
||||
}
|
||||
if ((a ??= b)) {
|
||||
}
|
||||
while (a ?? b) {}
|
||||
while ((a ??= b)) {}
|
||||
do {} while (a ?? b);
|
||||
for (let i = 0; a ?? b; i += 1) {}
|
||||
a ?? b ? true : false;
|
||||
```
|
||||
|
||||
### `ignoreMixedLogicalExpressions`
|
||||
|
||||
{/* insert option description */}
|
||||
|
||||
Generally expressions within mixed logical expressions intentionally use the falsy fallthrough behavior of the logical or operator, meaning that fixing the operator to the nullish coalesce operator could cause bugs.
|
||||
|
||||
If you're looking to enforce stricter conditional tests, you should consider using the `strict-boolean-expressions` rule.
|
||||
|
||||
Incorrect code for `ignoreMixedLogicalExpressions: false`, and correct code for `ignoreMixedLogicalExpressions: true`:
|
||||
|
||||
```ts option='{ "ignoreMixedLogicalExpressions": false }' showPlaygroundButton
|
||||
declare const a: string | null;
|
||||
declare const b: string | null;
|
||||
declare const c: string | null;
|
||||
declare const d: string | null;
|
||||
|
||||
a || (b && c);
|
||||
a ||= b && c;
|
||||
(a && b) || c || d;
|
||||
a || (b && c) || d;
|
||||
a || (b && c && d);
|
||||
```
|
||||
|
||||
Correct code for `ignoreMixedLogicalExpressions: false`:
|
||||
|
||||
```ts option='{ "ignoreMixedLogicalExpressions": false }' showPlaygroundButton
|
||||
declare const a: string | null;
|
||||
declare const b: string | null;
|
||||
declare const c: string | null;
|
||||
declare const d: string | null;
|
||||
|
||||
a ?? (b && c);
|
||||
a ??= b && c;
|
||||
(a && b) ?? c ?? d;
|
||||
a ?? (b && c) ?? d;
|
||||
a ?? (b && c && d);
|
||||
```
|
||||
|
||||
**_NOTE:_** Errors for this specific case will be presented as suggestions (see below), instead of fixes. This is because it is not always safe to automatically convert `||` to `??` within a mixed logical expression, as we cannot tell the intended precedence of the operator. Note that by design, `??` requires parentheses when used with `&&` or `||` in the same expression.
|
||||
|
||||
### `ignorePrimitives`
|
||||
|
||||
{/* insert option description */}
|
||||
|
||||
If you would like to ignore expressions containing operands of certain primitive types that can be falsy then you may pass an object containing a boolean value for each primitive:
|
||||
|
||||
- `string: true`, ignores `null` or `undefined` unions with `string` (default: false).
|
||||
- `number: true`, ignores `null` or `undefined` unions with `number` (default: false).
|
||||
- `bigint: true`, ignores `null` or `undefined` unions with `bigint` (default: false).
|
||||
- `boolean: true`, ignores `null` or `undefined` unions with `boolean` (default: false).
|
||||
|
||||
Incorrect code for `ignorePrimitives: { string: false }`, and correct code for `ignorePrimitives: { string: true }`:
|
||||
|
||||
```ts option='{ "ignorePrimitives": { "string": true } }' showPlaygroundButton
|
||||
const foo: string | undefined = 'bar';
|
||||
foo || 'a string';
|
||||
```
|
||||
|
||||
Correct code for both `ignorePrimitives: { string: false }` and `ignorePrimitives: { string: true }`:
|
||||
|
||||
```ts option='{ "ignorePrimitives": { "string": true } }' showPlaygroundButton
|
||||
const foo: string | undefined = 'bar';
|
||||
foo ?? 'a string';
|
||||
```
|
||||
|
||||
Also, if you would like to ignore all primitives types, you can set `ignorePrimitives: true`. It is equivalent to `ignorePrimitives: { string: true, number: true, bigint: true, boolean: true }`.
|
||||
|
||||
### `ignoreBooleanCoercion`
|
||||
|
||||
{/* insert option description */}
|
||||
|
||||
Whether to ignore expressions that coerce a value into a boolean: `Boolean(...)`.
|
||||
|
||||
Incorrect code for `ignoreBooleanCoercion: false`, and correct code for `ignoreBooleanCoercion: true`:
|
||||
|
||||
```ts option='{ "ignoreBooleanCoercion": true }' showPlaygroundButton
|
||||
let a: string | true | undefined;
|
||||
let b: string | boolean | undefined;
|
||||
|
||||
const x = Boolean(a || b);
|
||||
```
|
||||
|
||||
Correct code for `ignoreBooleanCoercion: false`:
|
||||
|
||||
```ts option='{ "ignoreBooleanCoercion": false }' showPlaygroundButton
|
||||
let a: string | true | undefined;
|
||||
let b: string | boolean | undefined;
|
||||
|
||||
const x = Boolean(a ?? b);
|
||||
```
|
||||
|
||||
### `allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing`
|
||||
|
||||
{/* insert option description */}
|
||||
|
||||
:::danger Deprecated
|
||||
|
||||
> This option will be removed in the next major version of typescript-eslint.
|
||||
> :::
|
||||
> Unless this is set to `true`, the rule will error on every file whose `tsconfig.json` does _not_ have the `strictNullChecks` compiler option (or `strict`) set to `true`.
|
||||
|
||||
Without `strictNullChecks`, TypeScript essentially erases `undefined` and `null` from the types. This means when this rule inspects the types from a variable, **it will not be able to tell that the variable might be `null` or `undefined`**, which essentially makes this rule useless.
|
||||
|
||||
You should be using `strictNullChecks` to ensure complete type-safety in your codebase.
|
||||
|
||||
If for some reason you cannot turn on `strictNullChecks`, but still want to use this rule - you can use this option to allow it - but know that the behavior of this rule is _undefined_ with the compiler option turned off. We will not accept bug reports if you are using this option.
|
||||
|
||||
## When Not To Use It
|
||||
|
||||
If you are not using TypeScript 3.7 (or greater), then you will not be able to use this rule, as the operator is not supported.
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [TypeScript 3.7 Release Notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html)
|
||||
- [Nullish Coalescing Operator Proposal](https://github.com/tc39/proposal-nullish-coalescing/)
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
declare const config: (style: 'glob' | 'minimatch') => {
|
||||
files: string[];
|
||||
rules: Record<string, 'error' | 'off' | 'warn'>;
|
||||
};
|
||||
export = config;
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
{
|
||||
"name": "@typescript-eslint/eslint-plugin",
|
||||
"version": "8.14.0",
|
||||
"description": "TypeScript plugin for ESLint",
|
||||
"files": [
|
||||
"dist",
|
||||
"docs",
|
||||
"eslint-recommended-raw.d.ts",
|
||||
"index.d.ts",
|
||||
"rules.d.ts",
|
||||
"package.json",
|
||||
"README.md",
|
||||
"LICENSE"
|
||||
],
|
||||
"type": "commonjs",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
},
|
||||
"./package.json": "./package.json",
|
||||
"./use-at-your-own-risk/rules": {
|
||||
"types": "./rules.d.ts",
|
||||
"default": "./dist/rules/index.js"
|
||||
},
|
||||
"./use-at-your-own-risk/eslint-recommended-raw": {
|
||||
"types": "./eslint-recommended-raw.d.ts",
|
||||
"default": "./dist/configs/eslint-recommended-raw.js"
|
||||
}
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
|
||||
"directory": "packages/eslint-plugin"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
|
||||
},
|
||||
"homepage": "https://typescript-eslint.io/packages/eslint-plugin",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"eslint",
|
||||
"eslintplugin",
|
||||
"eslint-plugin",
|
||||
"typescript"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc -b tsconfig.build.json",
|
||||
"clean": "tsc -b tsconfig.build.json --clean",
|
||||
"postclean": "rimraf dist && rimraf coverage",
|
||||
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
|
||||
"generate:breaking-changes": "tsx tools/generate-breaking-changes.mts",
|
||||
"generate:configs": "npx nx generate-configs repo",
|
||||
"lint": "npx nx lint",
|
||||
"test": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" jest --coverage --logHeapUsage",
|
||||
"test-single": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" jest --no-coverage",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@eslint-community/regexpp": "^4.10.0",
|
||||
"@typescript-eslint/scope-manager": "8.14.0",
|
||||
"@typescript-eslint/type-utils": "8.14.0",
|
||||
"@typescript-eslint/utils": "8.14.0",
|
||||
"@typescript-eslint/visitor-keys": "8.14.0",
|
||||
"graphemer": "^1.4.0",
|
||||
"ignore": "^5.3.1",
|
||||
"natural-compare": "^1.4.0",
|
||||
"ts-api-utils": "^1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jest/types": "29.6.3",
|
||||
"@types/marked": "^5.0.2",
|
||||
"@types/mdast": "^4.0.3",
|
||||
"@types/natural-compare": "*",
|
||||
"@typescript-eslint/rule-schema-to-typescript-types": "8.14.0",
|
||||
"@typescript-eslint/rule-tester": "8.14.0",
|
||||
"ajv": "^6.12.6",
|
||||
"cross-env": "^7.0.3",
|
||||
"cross-fetch": "*",
|
||||
"eslint": "^9.13.0",
|
||||
"jest": "29.7.0",
|
||||
"jest-specific-snapshot": "^8.0.0",
|
||||
"json-schema": "*",
|
||||
"markdown-table": "^3.0.3",
|
||||
"marked": "^5.1.2",
|
||||
"mdast-util-from-markdown": "^2.0.0",
|
||||
"mdast-util-mdx": "^3.0.0",
|
||||
"micromark-extension-mdxjs": "^3.0.0",
|
||||
"prettier": "^3.2.5",
|
||||
"rimraf": "*",
|
||||
"title-case": "^3.0.3",
|
||||
"tsx": "*",
|
||||
"typescript": "*",
|
||||
"unist-util-visit": "^5.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
|
||||
"eslint": "^8.57.0 || ^9.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"name": "@typescript-eslint/parser",
|
||||
"version": "8.14.0",
|
||||
"description": "An ESLint custom parser which leverages TypeScript ESTree",
|
||||
"files": [
|
||||
"dist",
|
||||
"_ts4.3",
|
||||
"README.md",
|
||||
"LICENSE"
|
||||
],
|
||||
"type": "commonjs",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
|
||||
"directory": "packages/parser"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
|
||||
},
|
||||
"homepage": "https://typescript-eslint.io/packages/parser",
|
||||
"license": "BSD-2-Clause",
|
||||
"keywords": [
|
||||
"ast",
|
||||
"ecmascript",
|
||||
"javascript",
|
||||
"typescript",
|
||||
"parser",
|
||||
"syntax",
|
||||
"eslint"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc -b tsconfig.build.json",
|
||||
"postbuild": "downlevel-dts dist _ts4.3/dist --to=4.3",
|
||||
"clean": "tsc -b tsconfig.build.json --clean",
|
||||
"postclean": "rimraf dist && rimraf _ts4.3 && rimraf coverage",
|
||||
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
|
||||
"lint": "npx nx lint",
|
||||
"test": "jest --coverage",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^8.57.0 || ^9.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.14.0",
|
||||
"@typescript-eslint/types": "8.14.0",
|
||||
"@typescript-eslint/typescript-estree": "8.14.0",
|
||||
"@typescript-eslint/visitor-keys": "8.14.0",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jest/types": "29.6.3",
|
||||
"@types/glob": "*",
|
||||
"downlevel-dts": "*",
|
||||
"glob": "*",
|
||||
"jest": "29.7.0",
|
||||
"prettier": "^3.2.5",
|
||||
"rimraf": "*",
|
||||
"typescript": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"typesVersions": {
|
||||
"<4.7": {
|
||||
"*": [
|
||||
"_ts4.3/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
"use strict";
|
||||
// THIS CODE WAS AUTOMATICALLY GENERATED
|
||||
// DO NOT EDIT THIS CODE BY HAND
|
||||
// RUN THE FOLLOWING COMMAND FROM THE WORKSPACE ROOT TO REGENERATE:
|
||||
// npx nx generate-lib repo
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.es2015_core = void 0;
|
||||
const base_config_1 = require("./base-config");
|
||||
exports.es2015_core = {
|
||||
Array: base_config_1.TYPE,
|
||||
ArrayConstructor: base_config_1.TYPE,
|
||||
DateConstructor: base_config_1.TYPE,
|
||||
Float32Array: base_config_1.TYPE,
|
||||
Float64Array: base_config_1.TYPE,
|
||||
Function: base_config_1.TYPE,
|
||||
Int8Array: base_config_1.TYPE,
|
||||
Int16Array: base_config_1.TYPE,
|
||||
Int32Array: base_config_1.TYPE,
|
||||
Math: base_config_1.TYPE,
|
||||
NumberConstructor: base_config_1.TYPE,
|
||||
ObjectConstructor: base_config_1.TYPE,
|
||||
ReadonlyArray: base_config_1.TYPE,
|
||||
RegExp: base_config_1.TYPE,
|
||||
RegExpConstructor: base_config_1.TYPE,
|
||||
String: base_config_1.TYPE,
|
||||
StringConstructor: base_config_1.TYPE,
|
||||
Uint8Array: base_config_1.TYPE,
|
||||
Uint8ClampedArray: base_config_1.TYPE,
|
||||
Uint16Array: base_config_1.TYPE,
|
||||
Uint32Array: base_config_1.TYPE,
|
||||
};
|
||||
//# sourceMappingURL=es2015.core.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"es2015.core.js","sourceRoot":"","sources":["../../src/lib/es2015.core.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+CAAqC;AAExB,QAAA,WAAW,GAAG;IACzB,KAAK,EAAE,kBAAI;IACX,gBAAgB,EAAE,kBAAI;IACtB,eAAe,EAAE,kBAAI;IACrB,YAAY,EAAE,kBAAI;IAClB,YAAY,EAAE,kBAAI;IAClB,QAAQ,EAAE,kBAAI;IACd,SAAS,EAAE,kBAAI;IACf,UAAU,EAAE,kBAAI;IAChB,UAAU,EAAE,kBAAI;IAChB,IAAI,EAAE,kBAAI;IACV,iBAAiB,EAAE,kBAAI;IACvB,iBAAiB,EAAE,kBAAI;IACvB,aAAa,EAAE,kBAAI;IACnB,MAAM,EAAE,kBAAI;IACZ,iBAAiB,EAAE,kBAAI;IACvB,MAAM,EAAE,kBAAI;IACZ,iBAAiB,EAAE,kBAAI;IACvB,UAAU,EAAE,kBAAI;IAChB,iBAAiB,EAAE,kBAAI;IACvB,WAAW,EAAE,kBAAI;IACjB,WAAW,EAAE,kBAAI;CAC4B,CAAC"}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
"use strict";
|
||||
// THIS CODE WAS AUTOMATICALLY GENERATED
|
||||
// DO NOT EDIT THIS CODE BY HAND
|
||||
// RUN THE FOLLOWING COMMAND FROM THE WORKSPACE ROOT TO REGENERATE:
|
||||
// npx nx generate-lib repo
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.es2015_iterable = void 0;
|
||||
const base_config_1 = require("./base-config");
|
||||
const es2015_symbol_1 = require("./es2015.symbol");
|
||||
exports.es2015_iterable = {
|
||||
...es2015_symbol_1.es2015_symbol,
|
||||
Array: base_config_1.TYPE,
|
||||
ArrayConstructor: base_config_1.TYPE,
|
||||
ArrayIterator: base_config_1.TYPE,
|
||||
BuiltinIteratorReturn: base_config_1.TYPE,
|
||||
Float32Array: base_config_1.TYPE,
|
||||
Float32ArrayConstructor: base_config_1.TYPE,
|
||||
Float64Array: base_config_1.TYPE,
|
||||
Float64ArrayConstructor: base_config_1.TYPE,
|
||||
IArguments: base_config_1.TYPE,
|
||||
Int8Array: base_config_1.TYPE,
|
||||
Int8ArrayConstructor: base_config_1.TYPE,
|
||||
Int16Array: base_config_1.TYPE,
|
||||
Int16ArrayConstructor: base_config_1.TYPE,
|
||||
Int32Array: base_config_1.TYPE,
|
||||
Int32ArrayConstructor: base_config_1.TYPE,
|
||||
Iterable: base_config_1.TYPE,
|
||||
IterableIterator: base_config_1.TYPE,
|
||||
Iterator: base_config_1.TYPE,
|
||||
IteratorObject: base_config_1.TYPE,
|
||||
IteratorResult: base_config_1.TYPE,
|
||||
IteratorReturnResult: base_config_1.TYPE,
|
||||
IteratorYieldResult: base_config_1.TYPE,
|
||||
Map: base_config_1.TYPE,
|
||||
MapConstructor: base_config_1.TYPE,
|
||||
MapIterator: base_config_1.TYPE,
|
||||
Promise: base_config_1.TYPE,
|
||||
PromiseConstructor: base_config_1.TYPE,
|
||||
ReadonlyArray: base_config_1.TYPE,
|
||||
ReadonlyMap: base_config_1.TYPE,
|
||||
ReadonlySet: base_config_1.TYPE,
|
||||
Set: base_config_1.TYPE,
|
||||
SetConstructor: base_config_1.TYPE,
|
||||
SetIterator: base_config_1.TYPE,
|
||||
String: base_config_1.TYPE,
|
||||
StringIterator: base_config_1.TYPE,
|
||||
SymbolConstructor: base_config_1.TYPE,
|
||||
Uint8Array: base_config_1.TYPE,
|
||||
Uint8ArrayConstructor: base_config_1.TYPE,
|
||||
Uint8ClampedArray: base_config_1.TYPE,
|
||||
Uint8ClampedArrayConstructor: base_config_1.TYPE,
|
||||
Uint16Array: base_config_1.TYPE,
|
||||
Uint16ArrayConstructor: base_config_1.TYPE,
|
||||
Uint32Array: base_config_1.TYPE,
|
||||
Uint32ArrayConstructor: base_config_1.TYPE,
|
||||
WeakMap: base_config_1.TYPE,
|
||||
WeakMapConstructor: base_config_1.TYPE,
|
||||
WeakSet: base_config_1.TYPE,
|
||||
WeakSetConstructor: base_config_1.TYPE,
|
||||
};
|
||||
//# sourceMappingURL=es2015.iterable.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"es2015.iterable.js","sourceRoot":"","sources":["../../src/lib/es2015.iterable.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+CAAqC;AACrC,mDAAgD;AAEnC,QAAA,eAAe,GAAG;IAC7B,GAAG,6BAAa;IAChB,KAAK,EAAE,kBAAI;IACX,gBAAgB,EAAE,kBAAI;IACtB,aAAa,EAAE,kBAAI;IACnB,qBAAqB,EAAE,kBAAI;IAC3B,YAAY,EAAE,kBAAI;IAClB,uBAAuB,EAAE,kBAAI;IAC7B,YAAY,EAAE,kBAAI;IAClB,uBAAuB,EAAE,kBAAI;IAC7B,UAAU,EAAE,kBAAI;IAChB,SAAS,EAAE,kBAAI;IACf,oBAAoB,EAAE,kBAAI;IAC1B,UAAU,EAAE,kBAAI;IAChB,qBAAqB,EAAE,kBAAI;IAC3B,UAAU,EAAE,kBAAI;IAChB,qBAAqB,EAAE,kBAAI;IAC3B,QAAQ,EAAE,kBAAI;IACd,gBAAgB,EAAE,kBAAI;IACtB,QAAQ,EAAE,kBAAI;IACd,cAAc,EAAE,kBAAI;IACpB,cAAc,EAAE,kBAAI;IACpB,oBAAoB,EAAE,kBAAI;IAC1B,mBAAmB,EAAE,kBAAI;IACzB,GAAG,EAAE,kBAAI;IACT,cAAc,EAAE,kBAAI;IACpB,WAAW,EAAE,kBAAI;IACjB,OAAO,EAAE,kBAAI;IACb,kBAAkB,EAAE,kBAAI;IACxB,aAAa,EAAE,kBAAI;IACnB,WAAW,EAAE,kBAAI;IACjB,WAAW,EAAE,kBAAI;IACjB,GAAG,EAAE,kBAAI;IACT,cAAc,EAAE,kBAAI;IACpB,WAAW,EAAE,kBAAI;IACjB,MAAM,EAAE,kBAAI;IACZ,cAAc,EAAE,kBAAI;IACpB,iBAAiB,EAAE,kBAAI;IACvB,UAAU,EAAE,kBAAI;IAChB,qBAAqB,EAAE,kBAAI;IAC3B,iBAAiB,EAAE,kBAAI;IACvB,4BAA4B,EAAE,kBAAI;IAClC,WAAW,EAAE,kBAAI;IACjB,sBAAsB,EAAE,kBAAI;IAC5B,WAAW,EAAE,kBAAI;IACjB,sBAAsB,EAAE,kBAAI;IAC5B,OAAO,EAAE,kBAAI;IACb,kBAAkB,EAAE,kBAAI;IACxB,OAAO,EAAE,kBAAI;IACb,kBAAkB,EAAE,kBAAI;CACqB,CAAC"}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
"use strict";
|
||||
// THIS CODE WAS AUTOMATICALLY GENERATED
|
||||
// DO NOT EDIT THIS CODE BY HAND
|
||||
// RUN THE FOLLOWING COMMAND FROM THE WORKSPACE ROOT TO REGENERATE:
|
||||
// npx nx generate-lib repo
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.es2015 = void 0;
|
||||
const es5_1 = require("./es5");
|
||||
const es2015_collection_1 = require("./es2015.collection");
|
||||
const es2015_core_1 = require("./es2015.core");
|
||||
const es2015_generator_1 = require("./es2015.generator");
|
||||
const es2015_iterable_1 = require("./es2015.iterable");
|
||||
const es2015_promise_1 = require("./es2015.promise");
|
||||
const es2015_proxy_1 = require("./es2015.proxy");
|
||||
const es2015_reflect_1 = require("./es2015.reflect");
|
||||
const es2015_symbol_1 = require("./es2015.symbol");
|
||||
const es2015_symbol_wellknown_1 = require("./es2015.symbol.wellknown");
|
||||
exports.es2015 = {
|
||||
...es5_1.es5,
|
||||
...es2015_core_1.es2015_core,
|
||||
...es2015_collection_1.es2015_collection,
|
||||
...es2015_iterable_1.es2015_iterable,
|
||||
...es2015_generator_1.es2015_generator,
|
||||
...es2015_promise_1.es2015_promise,
|
||||
...es2015_proxy_1.es2015_proxy,
|
||||
...es2015_reflect_1.es2015_reflect,
|
||||
...es2015_symbol_1.es2015_symbol,
|
||||
...es2015_symbol_wellknown_1.es2015_symbol_wellknown,
|
||||
};
|
||||
//# sourceMappingURL=es2015.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"es2015.js","sourceRoot":"","sources":["../../src/lib/es2015.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+BAA4B;AAC5B,2DAAwD;AACxD,+CAA4C;AAC5C,yDAAsD;AACtD,uDAAoD;AACpD,qDAAkD;AAClD,iDAA8C;AAC9C,qDAAkD;AAClD,mDAAgD;AAChD,uEAAoE;AAEvD,QAAA,MAAM,GAAG;IACpB,GAAG,SAAG;IACN,GAAG,yBAAW;IACd,GAAG,qCAAiB;IACpB,GAAG,iCAAe;IAClB,GAAG,mCAAgB;IACnB,GAAG,+BAAc;IACjB,GAAG,2BAAY;IACf,GAAG,+BAAc;IACjB,GAAG,6BAAa;IAChB,GAAG,iDAAuB;CACmB,CAAC"}
|
||||
Generated
Vendored
+46
@@ -0,0 +1,46 @@
|
||||
"use strict";
|
||||
// THIS CODE WAS AUTOMATICALLY GENERATED
|
||||
// DO NOT EDIT THIS CODE BY HAND
|
||||
// RUN THE FOLLOWING COMMAND FROM THE WORKSPACE ROOT TO REGENERATE:
|
||||
// npx nx generate-lib repo
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.es2015_symbol_wellknown = void 0;
|
||||
const base_config_1 = require("./base-config");
|
||||
const es2015_symbol_1 = require("./es2015.symbol");
|
||||
exports.es2015_symbol_wellknown = {
|
||||
...es2015_symbol_1.es2015_symbol,
|
||||
Array: base_config_1.TYPE,
|
||||
ArrayBuffer: base_config_1.TYPE,
|
||||
ArrayBufferConstructor: base_config_1.TYPE,
|
||||
ArrayConstructor: base_config_1.TYPE,
|
||||
DataView: base_config_1.TYPE,
|
||||
Date: base_config_1.TYPE,
|
||||
Float32Array: base_config_1.TYPE,
|
||||
Float64Array: base_config_1.TYPE,
|
||||
Function: base_config_1.TYPE,
|
||||
GeneratorFunction: base_config_1.TYPE,
|
||||
Int8Array: base_config_1.TYPE,
|
||||
Int16Array: base_config_1.TYPE,
|
||||
Int32Array: base_config_1.TYPE,
|
||||
JSON: base_config_1.TYPE,
|
||||
Map: base_config_1.TYPE,
|
||||
MapConstructor: base_config_1.TYPE,
|
||||
Math: base_config_1.TYPE,
|
||||
Promise: base_config_1.TYPE,
|
||||
PromiseConstructor: base_config_1.TYPE,
|
||||
ReadonlyArray: base_config_1.TYPE,
|
||||
RegExp: base_config_1.TYPE,
|
||||
RegExpConstructor: base_config_1.TYPE,
|
||||
Set: base_config_1.TYPE,
|
||||
SetConstructor: base_config_1.TYPE,
|
||||
String: base_config_1.TYPE,
|
||||
Symbol: base_config_1.TYPE,
|
||||
SymbolConstructor: base_config_1.TYPE,
|
||||
Uint8Array: base_config_1.TYPE,
|
||||
Uint8ClampedArray: base_config_1.TYPE,
|
||||
Uint16Array: base_config_1.TYPE,
|
||||
Uint32Array: base_config_1.TYPE,
|
||||
WeakMap: base_config_1.TYPE,
|
||||
WeakSet: base_config_1.TYPE,
|
||||
};
|
||||
//# sourceMappingURL=es2015.symbol.wellknown.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"es2015.symbol.wellknown.js","sourceRoot":"","sources":["../../src/lib/es2015.symbol.wellknown.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+CAAqC;AACrC,mDAAgD;AAEnC,QAAA,uBAAuB,GAAG;IACrC,GAAG,6BAAa;IAChB,KAAK,EAAE,kBAAI;IACX,WAAW,EAAE,kBAAI;IACjB,sBAAsB,EAAE,kBAAI;IAC5B,gBAAgB,EAAE,kBAAI;IACtB,QAAQ,EAAE,kBAAI;IACd,IAAI,EAAE,kBAAI;IACV,YAAY,EAAE,kBAAI;IAClB,YAAY,EAAE,kBAAI;IAClB,QAAQ,EAAE,kBAAI;IACd,iBAAiB,EAAE,kBAAI;IACvB,SAAS,EAAE,kBAAI;IACf,UAAU,EAAE,kBAAI;IAChB,UAAU,EAAE,kBAAI;IAChB,IAAI,EAAE,kBAAI;IACV,GAAG,EAAE,kBAAI;IACT,cAAc,EAAE,kBAAI;IACpB,IAAI,EAAE,kBAAI;IACV,OAAO,EAAE,kBAAI;IACb,kBAAkB,EAAE,kBAAI;IACxB,aAAa,EAAE,kBAAI;IACnB,MAAM,EAAE,kBAAI;IACZ,iBAAiB,EAAE,kBAAI;IACvB,GAAG,EAAE,kBAAI;IACT,cAAc,EAAE,kBAAI;IACpB,MAAM,EAAE,kBAAI;IACZ,MAAM,EAAE,kBAAI;IACZ,iBAAiB,EAAE,kBAAI;IACvB,UAAU,EAAE,kBAAI;IAChB,iBAAiB,EAAE,kBAAI;IACvB,WAAW,EAAE,kBAAI;IACjB,WAAW,EAAE,kBAAI;IACjB,OAAO,EAAE,kBAAI;IACb,OAAO,EAAE,kBAAI;CACgC,CAAC"}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
"use strict";
|
||||
// THIS CODE WAS AUTOMATICALLY GENERATED
|
||||
// DO NOT EDIT THIS CODE BY HAND
|
||||
// RUN THE FOLLOWING COMMAND FROM THE WORKSPACE ROOT TO REGENERATE:
|
||||
// npx nx generate-lib repo
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.es2016_array_include = void 0;
|
||||
const base_config_1 = require("./base-config");
|
||||
exports.es2016_array_include = {
|
||||
Array: base_config_1.TYPE,
|
||||
Float32Array: base_config_1.TYPE,
|
||||
Float64Array: base_config_1.TYPE,
|
||||
Int8Array: base_config_1.TYPE,
|
||||
Int16Array: base_config_1.TYPE,
|
||||
Int32Array: base_config_1.TYPE,
|
||||
ReadonlyArray: base_config_1.TYPE,
|
||||
Uint8Array: base_config_1.TYPE,
|
||||
Uint8ClampedArray: base_config_1.TYPE,
|
||||
Uint16Array: base_config_1.TYPE,
|
||||
Uint32Array: base_config_1.TYPE,
|
||||
};
|
||||
//# sourceMappingURL=es2016.array.include.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"es2016.array.include.js","sourceRoot":"","sources":["../../src/lib/es2016.array.include.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+CAAqC;AAExB,QAAA,oBAAoB,GAAG;IAClC,KAAK,EAAE,kBAAI;IACX,YAAY,EAAE,kBAAI;IAClB,YAAY,EAAE,kBAAI;IAClB,SAAS,EAAE,kBAAI;IACf,UAAU,EAAE,kBAAI;IAChB,UAAU,EAAE,kBAAI;IAChB,aAAa,EAAE,kBAAI;IACnB,UAAU,EAAE,kBAAI;IAChB,iBAAiB,EAAE,kBAAI;IACvB,WAAW,EAAE,kBAAI;IACjB,WAAW,EAAE,kBAAI;CAC4B,CAAC"}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
// THIS CODE WAS AUTOMATICALLY GENERATED
|
||||
// DO NOT EDIT THIS CODE BY HAND
|
||||
// RUN THE FOLLOWING COMMAND FROM THE WORKSPACE ROOT TO REGENERATE:
|
||||
// npx nx generate-lib repo
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.es2017_typedarrays = void 0;
|
||||
const base_config_1 = require("./base-config");
|
||||
exports.es2017_typedarrays = {
|
||||
Float32ArrayConstructor: base_config_1.TYPE,
|
||||
Float64ArrayConstructor: base_config_1.TYPE,
|
||||
Int8ArrayConstructor: base_config_1.TYPE,
|
||||
Int16ArrayConstructor: base_config_1.TYPE,
|
||||
Int32ArrayConstructor: base_config_1.TYPE,
|
||||
Uint8ArrayConstructor: base_config_1.TYPE,
|
||||
Uint8ClampedArrayConstructor: base_config_1.TYPE,
|
||||
Uint16ArrayConstructor: base_config_1.TYPE,
|
||||
Uint32ArrayConstructor: base_config_1.TYPE,
|
||||
};
|
||||
//# sourceMappingURL=es2017.typedarrays.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"es2017.typedarrays.js","sourceRoot":"","sources":["../../src/lib/es2017.typedarrays.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+CAAqC;AAExB,QAAA,kBAAkB,GAAG;IAChC,uBAAuB,EAAE,kBAAI;IAC7B,uBAAuB,EAAE,kBAAI;IAC7B,oBAAoB,EAAE,kBAAI;IAC1B,qBAAqB,EAAE,kBAAI;IAC3B,qBAAqB,EAAE,kBAAI;IAC3B,qBAAqB,EAAE,kBAAI;IAC3B,4BAA4B,EAAE,kBAAI;IAClC,sBAAsB,EAAE,kBAAI;IAC5B,sBAAsB,EAAE,kBAAI;CACiB,CAAC"}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
// THIS CODE WAS AUTOMATICALLY GENERATED
|
||||
// DO NOT EDIT THIS CODE BY HAND
|
||||
// RUN THE FOLLOWING COMMAND FROM THE WORKSPACE ROOT TO REGENERATE:
|
||||
// npx nx generate-lib repo
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.es2022_array = void 0;
|
||||
const base_config_1 = require("./base-config");
|
||||
exports.es2022_array = {
|
||||
Array: base_config_1.TYPE,
|
||||
BigInt64Array: base_config_1.TYPE,
|
||||
BigUint64Array: base_config_1.TYPE,
|
||||
Float32Array: base_config_1.TYPE,
|
||||
Float64Array: base_config_1.TYPE,
|
||||
Int8Array: base_config_1.TYPE,
|
||||
Int16Array: base_config_1.TYPE,
|
||||
Int32Array: base_config_1.TYPE,
|
||||
ReadonlyArray: base_config_1.TYPE,
|
||||
Uint8Array: base_config_1.TYPE,
|
||||
Uint8ClampedArray: base_config_1.TYPE,
|
||||
Uint16Array: base_config_1.TYPE,
|
||||
Uint32Array: base_config_1.TYPE,
|
||||
};
|
||||
//# sourceMappingURL=es2022.array.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"es2022.array.js","sourceRoot":"","sources":["../../src/lib/es2022.array.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+CAAqC;AAExB,QAAA,YAAY,GAAG;IAC1B,KAAK,EAAE,kBAAI;IACX,aAAa,EAAE,kBAAI;IACnB,cAAc,EAAE,kBAAI;IACpB,YAAY,EAAE,kBAAI;IAClB,YAAY,EAAE,kBAAI;IAClB,SAAS,EAAE,kBAAI;IACf,UAAU,EAAE,kBAAI;IAChB,UAAU,EAAE,kBAAI;IAChB,aAAa,EAAE,kBAAI;IACnB,UAAU,EAAE,kBAAI;IAChB,iBAAiB,EAAE,kBAAI;IACvB,WAAW,EAAE,kBAAI;IACjB,WAAW,EAAE,kBAAI;CAC4B,CAAC"}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
// THIS CODE WAS AUTOMATICALLY GENERATED
|
||||
// DO NOT EDIT THIS CODE BY HAND
|
||||
// RUN THE FOLLOWING COMMAND FROM THE WORKSPACE ROOT TO REGENERATE:
|
||||
// npx nx generate-lib repo
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.es2023_array = void 0;
|
||||
const base_config_1 = require("./base-config");
|
||||
exports.es2023_array = {
|
||||
Array: base_config_1.TYPE,
|
||||
BigInt64Array: base_config_1.TYPE,
|
||||
BigUint64Array: base_config_1.TYPE,
|
||||
Float32Array: base_config_1.TYPE,
|
||||
Float64Array: base_config_1.TYPE,
|
||||
Int8Array: base_config_1.TYPE,
|
||||
Int16Array: base_config_1.TYPE,
|
||||
Int32Array: base_config_1.TYPE,
|
||||
ReadonlyArray: base_config_1.TYPE,
|
||||
Uint8Array: base_config_1.TYPE,
|
||||
Uint8ClampedArray: base_config_1.TYPE,
|
||||
Uint16Array: base_config_1.TYPE,
|
||||
Uint32Array: base_config_1.TYPE,
|
||||
};
|
||||
//# sourceMappingURL=es2023.array.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"es2023.array.js","sourceRoot":"","sources":["../../src/lib/es2023.array.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+CAAqC;AAExB,QAAA,YAAY,GAAG;IAC1B,KAAK,EAAE,kBAAI;IACX,aAAa,EAAE,kBAAI;IACnB,cAAc,EAAE,kBAAI;IACpB,YAAY,EAAE,kBAAI;IAClB,YAAY,EAAE,kBAAI;IAClB,SAAS,EAAE,kBAAI;IACf,UAAU,EAAE,kBAAI;IAChB,UAAU,EAAE,kBAAI;IAChB,aAAa,EAAE,kBAAI;IACnB,UAAU,EAAE,kBAAI;IAChB,iBAAiB,EAAE,kBAAI;IACvB,WAAW,EAAE,kBAAI;IACjB,WAAW,EAAE,kBAAI;CAC4B,CAAC"}
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
"use strict";
|
||||
// THIS CODE WAS AUTOMATICALLY GENERATED
|
||||
// DO NOT EDIT THIS CODE BY HAND
|
||||
// RUN THE FOLLOWING COMMAND FROM THE WORKSPACE ROOT TO REGENERATE:
|
||||
// npx nx generate-lib repo
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.es5 = void 0;
|
||||
const base_config_1 = require("./base-config");
|
||||
const decorators_1 = require("./decorators");
|
||||
const decorators_legacy_1 = require("./decorators.legacy");
|
||||
exports.es5 = {
|
||||
...decorators_1.decorators,
|
||||
...decorators_legacy_1.decorators_legacy,
|
||||
Array: base_config_1.TYPE_VALUE,
|
||||
ArrayBuffer: base_config_1.TYPE_VALUE,
|
||||
ArrayBufferConstructor: base_config_1.TYPE,
|
||||
ArrayBufferLike: base_config_1.TYPE,
|
||||
ArrayBufferTypes: base_config_1.TYPE,
|
||||
ArrayBufferView: base_config_1.TYPE,
|
||||
ArrayConstructor: base_config_1.TYPE,
|
||||
ArrayLike: base_config_1.TYPE,
|
||||
Awaited: base_config_1.TYPE,
|
||||
Boolean: base_config_1.TYPE_VALUE,
|
||||
BooleanConstructor: base_config_1.TYPE,
|
||||
CallableFunction: base_config_1.TYPE,
|
||||
Capitalize: base_config_1.TYPE,
|
||||
ConcatArray: base_config_1.TYPE,
|
||||
ConstructorParameters: base_config_1.TYPE,
|
||||
DataView: base_config_1.TYPE_VALUE,
|
||||
DataViewConstructor: base_config_1.TYPE,
|
||||
Date: base_config_1.TYPE_VALUE,
|
||||
DateConstructor: base_config_1.TYPE,
|
||||
Error: base_config_1.TYPE_VALUE,
|
||||
ErrorConstructor: base_config_1.TYPE,
|
||||
EvalError: base_config_1.TYPE_VALUE,
|
||||
EvalErrorConstructor: base_config_1.TYPE,
|
||||
Exclude: base_config_1.TYPE,
|
||||
Extract: base_config_1.TYPE,
|
||||
Float32Array: base_config_1.TYPE_VALUE,
|
||||
Float32ArrayConstructor: base_config_1.TYPE,
|
||||
Float64Array: base_config_1.TYPE_VALUE,
|
||||
Float64ArrayConstructor: base_config_1.TYPE,
|
||||
Function: base_config_1.TYPE_VALUE,
|
||||
FunctionConstructor: base_config_1.TYPE,
|
||||
IArguments: base_config_1.TYPE,
|
||||
ImportAssertions: base_config_1.TYPE,
|
||||
ImportAttributes: base_config_1.TYPE,
|
||||
ImportCallOptions: base_config_1.TYPE,
|
||||
ImportMeta: base_config_1.TYPE,
|
||||
InstanceType: base_config_1.TYPE,
|
||||
Int8Array: base_config_1.TYPE_VALUE,
|
||||
Int8ArrayConstructor: base_config_1.TYPE,
|
||||
Int16Array: base_config_1.TYPE_VALUE,
|
||||
Int16ArrayConstructor: base_config_1.TYPE,
|
||||
Int32Array: base_config_1.TYPE_VALUE,
|
||||
Int32ArrayConstructor: base_config_1.TYPE,
|
||||
Intl: base_config_1.TYPE_VALUE,
|
||||
JSON: base_config_1.TYPE_VALUE,
|
||||
Lowercase: base_config_1.TYPE,
|
||||
Math: base_config_1.TYPE_VALUE,
|
||||
NewableFunction: base_config_1.TYPE,
|
||||
NoInfer: base_config_1.TYPE,
|
||||
NonNullable: base_config_1.TYPE,
|
||||
Number: base_config_1.TYPE_VALUE,
|
||||
NumberConstructor: base_config_1.TYPE,
|
||||
Object: base_config_1.TYPE_VALUE,
|
||||
ObjectConstructor: base_config_1.TYPE,
|
||||
Omit: base_config_1.TYPE,
|
||||
OmitThisParameter: base_config_1.TYPE,
|
||||
Parameters: base_config_1.TYPE,
|
||||
Partial: base_config_1.TYPE,
|
||||
Pick: base_config_1.TYPE,
|
||||
Promise: base_config_1.TYPE,
|
||||
PromiseConstructorLike: base_config_1.TYPE,
|
||||
PromiseLike: base_config_1.TYPE,
|
||||
PropertyDescriptor: base_config_1.TYPE,
|
||||
PropertyDescriptorMap: base_config_1.TYPE,
|
||||
PropertyKey: base_config_1.TYPE,
|
||||
RangeError: base_config_1.TYPE_VALUE,
|
||||
RangeErrorConstructor: base_config_1.TYPE,
|
||||
Readonly: base_config_1.TYPE,
|
||||
ReadonlyArray: base_config_1.TYPE,
|
||||
Record: base_config_1.TYPE,
|
||||
ReferenceError: base_config_1.TYPE_VALUE,
|
||||
ReferenceErrorConstructor: base_config_1.TYPE,
|
||||
RegExp: base_config_1.TYPE_VALUE,
|
||||
RegExpConstructor: base_config_1.TYPE,
|
||||
RegExpExecArray: base_config_1.TYPE,
|
||||
RegExpMatchArray: base_config_1.TYPE,
|
||||
Required: base_config_1.TYPE,
|
||||
ReturnType: base_config_1.TYPE,
|
||||
String: base_config_1.TYPE_VALUE,
|
||||
StringConstructor: base_config_1.TYPE,
|
||||
Symbol: base_config_1.TYPE,
|
||||
SyntaxError: base_config_1.TYPE_VALUE,
|
||||
SyntaxErrorConstructor: base_config_1.TYPE,
|
||||
TemplateStringsArray: base_config_1.TYPE,
|
||||
ThisParameterType: base_config_1.TYPE,
|
||||
ThisType: base_config_1.TYPE,
|
||||
TypedPropertyDescriptor: base_config_1.TYPE,
|
||||
TypeError: base_config_1.TYPE_VALUE,
|
||||
TypeErrorConstructor: base_config_1.TYPE,
|
||||
Uint8Array: base_config_1.TYPE_VALUE,
|
||||
Uint8ArrayConstructor: base_config_1.TYPE,
|
||||
Uint8ClampedArray: base_config_1.TYPE_VALUE,
|
||||
Uint8ClampedArrayConstructor: base_config_1.TYPE,
|
||||
Uint16Array: base_config_1.TYPE_VALUE,
|
||||
Uint16ArrayConstructor: base_config_1.TYPE,
|
||||
Uint32Array: base_config_1.TYPE_VALUE,
|
||||
Uint32ArrayConstructor: base_config_1.TYPE,
|
||||
Uncapitalize: base_config_1.TYPE,
|
||||
Uppercase: base_config_1.TYPE,
|
||||
URIError: base_config_1.TYPE_VALUE,
|
||||
URIErrorConstructor: base_config_1.TYPE,
|
||||
WeakKey: base_config_1.TYPE,
|
||||
WeakKeyTypes: base_config_1.TYPE,
|
||||
};
|
||||
//# sourceMappingURL=es5.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"es5.js","sourceRoot":"","sources":["../../src/lib/es5.ts"],"names":[],"mappings":"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"}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
"use strict";
|
||||
// THIS CODE WAS AUTOMATICALLY GENERATED
|
||||
// DO NOT EDIT THIS CODE BY HAND
|
||||
// RUN THE FOLLOWING COMMAND FROM THE WORKSPACE ROOT TO REGENERATE:
|
||||
// npx nx generate-lib repo
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.es6 = void 0;
|
||||
const es5_1 = require("./es5");
|
||||
const es2015_collection_1 = require("./es2015.collection");
|
||||
const es2015_core_1 = require("./es2015.core");
|
||||
const es2015_generator_1 = require("./es2015.generator");
|
||||
const es2015_iterable_1 = require("./es2015.iterable");
|
||||
const es2015_promise_1 = require("./es2015.promise");
|
||||
const es2015_proxy_1 = require("./es2015.proxy");
|
||||
const es2015_reflect_1 = require("./es2015.reflect");
|
||||
const es2015_symbol_1 = require("./es2015.symbol");
|
||||
const es2015_symbol_wellknown_1 = require("./es2015.symbol.wellknown");
|
||||
exports.es6 = {
|
||||
...es5_1.es5,
|
||||
...es2015_core_1.es2015_core,
|
||||
...es2015_collection_1.es2015_collection,
|
||||
...es2015_iterable_1.es2015_iterable,
|
||||
...es2015_generator_1.es2015_generator,
|
||||
...es2015_promise_1.es2015_promise,
|
||||
...es2015_proxy_1.es2015_proxy,
|
||||
...es2015_reflect_1.es2015_reflect,
|
||||
...es2015_symbol_1.es2015_symbol,
|
||||
...es2015_symbol_wellknown_1.es2015_symbol_wellknown,
|
||||
};
|
||||
//# sourceMappingURL=es6.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"es6.js","sourceRoot":"","sources":["../../src/lib/es6.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,gCAAgC;AAChC,mEAAmE;AACnE,2BAA2B;;;AAI3B,+BAA4B;AAC5B,2DAAwD;AACxD,+CAA4C;AAC5C,yDAAsD;AACtD,uDAAoD;AACpD,qDAAkD;AAClD,iDAA8C;AAC9C,qDAAkD;AAClD,mDAAgD;AAChD,uEAAoE;AAEvD,QAAA,GAAG,GAAG;IACjB,GAAG,SAAG;IACN,GAAG,yBAAW;IACd,GAAG,qCAAiB;IACpB,GAAG,iCAAe;IAClB,GAAG,mCAAgB;IACnB,GAAG,+BAAc;IACjB,GAAG,2BAAY;IACf,GAAG,+BAAc;IACjB,GAAG,6BAAa;IAChB,GAAG,iDAAuB;CACmB,CAAC"}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
declare const lib: {
|
||||
readonly decorators: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'decorators.legacy': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly dom: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'dom.asynciterable': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'dom.iterable': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly es5: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly es6: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly es7: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly es2015: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2015.collection': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2015.core': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2015.generator': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2015.iterable': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2015.promise': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2015.proxy': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2015.reflect': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2015.symbol': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2015.symbol.wellknown': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly es2016: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2016.array.include': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2016.full': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2016.intl': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly es2017: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2017.date': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2017.full': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2017.intl': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2017.object': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2017.sharedmemory': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2017.string': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2017.typedarrays': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly es2018: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2018.asyncgenerator': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2018.asynciterable': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2018.full': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2018.intl': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2018.promise': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2018.regexp': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly es2019: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2019.array': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2019.full': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2019.intl': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2019.object': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2019.string': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2019.symbol': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly es2020: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2020.bigint': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2020.date': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2020.full': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2020.intl': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2020.number': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2020.promise': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2020.sharedmemory': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2020.string': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2020.symbol.wellknown': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly es2021: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2021.full': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2021.intl': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2021.promise': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2021.string': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2021.weakref': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly es2022: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2022.array': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2022.error': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2022.full': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2022.intl': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2022.object': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2022.regexp': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2022.sharedmemory': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2022.string': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly es2023: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2023.array': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2023.collection': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2023.full': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'es2023.intl': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly esnext: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'esnext.array': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'esnext.asynciterable': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'esnext.bigint': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'esnext.collection': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'esnext.decorators': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'esnext.disposable': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'esnext.full': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'esnext.intl': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'esnext.iterator': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'esnext.object': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'esnext.promise': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'esnext.regexp': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'esnext.string': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'esnext.symbol': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'esnext.weakref': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly lib: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly scripthost: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly webworker: Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'webworker.asynciterable': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'webworker.importscripts': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
readonly 'webworker.iterable': Record<string, import("..").ImplicitLibVariableOptions>;
|
||||
};
|
||||
export { lib };
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
"use strict";
|
||||
// THIS CODE WAS AUTOMATICALLY GENERATED
|
||||
// DO NOT EDIT THIS CODE BY HAND
|
||||
// RUN THE FOLLOWING COMMAND FROM THE WORKSPACE ROOT TO REGENERATE:
|
||||
// npx nx generate-lib repo
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.lib = void 0;
|
||||
const decorators_1 = require("./decorators");
|
||||
const decorators_legacy_1 = require("./decorators.legacy");
|
||||
const dom_1 = require("./dom");
|
||||
const dom_asynciterable_1 = require("./dom.asynciterable");
|
||||
const dom_iterable_1 = require("./dom.iterable");
|
||||
const es5_1 = require("./es5");
|
||||
const es6_1 = require("./es6");
|
||||
const es7_1 = require("./es7");
|
||||
const es2015_1 = require("./es2015");
|
||||
const es2015_collection_1 = require("./es2015.collection");
|
||||
const es2015_core_1 = require("./es2015.core");
|
||||
const es2015_generator_1 = require("./es2015.generator");
|
||||
const es2015_iterable_1 = require("./es2015.iterable");
|
||||
const es2015_promise_1 = require("./es2015.promise");
|
||||
const es2015_proxy_1 = require("./es2015.proxy");
|
||||
const es2015_reflect_1 = require("./es2015.reflect");
|
||||
const es2015_symbol_1 = require("./es2015.symbol");
|
||||
const es2015_symbol_wellknown_1 = require("./es2015.symbol.wellknown");
|
||||
const es2016_1 = require("./es2016");
|
||||
const es2016_array_include_1 = require("./es2016.array.include");
|
||||
const es2016_full_1 = require("./es2016.full");
|
||||
const es2016_intl_1 = require("./es2016.intl");
|
||||
const es2017_1 = require("./es2017");
|
||||
const es2017_date_1 = require("./es2017.date");
|
||||
const es2017_full_1 = require("./es2017.full");
|
||||
const es2017_intl_1 = require("./es2017.intl");
|
||||
const es2017_object_1 = require("./es2017.object");
|
||||
const es2017_sharedmemory_1 = require("./es2017.sharedmemory");
|
||||
const es2017_string_1 = require("./es2017.string");
|
||||
const es2017_typedarrays_1 = require("./es2017.typedarrays");
|
||||
const es2018_1 = require("./es2018");
|
||||
const es2018_asyncgenerator_1 = require("./es2018.asyncgenerator");
|
||||
const es2018_asynciterable_1 = require("./es2018.asynciterable");
|
||||
const es2018_full_1 = require("./es2018.full");
|
||||
const es2018_intl_1 = require("./es2018.intl");
|
||||
const es2018_promise_1 = require("./es2018.promise");
|
||||
const es2018_regexp_1 = require("./es2018.regexp");
|
||||
const es2019_1 = require("./es2019");
|
||||
const es2019_array_1 = require("./es2019.array");
|
||||
const es2019_full_1 = require("./es2019.full");
|
||||
const es2019_intl_1 = require("./es2019.intl");
|
||||
const es2019_object_1 = require("./es2019.object");
|
||||
const es2019_string_1 = require("./es2019.string");
|
||||
const es2019_symbol_1 = require("./es2019.symbol");
|
||||
const es2020_1 = require("./es2020");
|
||||
const es2020_bigint_1 = require("./es2020.bigint");
|
||||
const es2020_date_1 = require("./es2020.date");
|
||||
const es2020_full_1 = require("./es2020.full");
|
||||
const es2020_intl_1 = require("./es2020.intl");
|
||||
const es2020_number_1 = require("./es2020.number");
|
||||
const es2020_promise_1 = require("./es2020.promise");
|
||||
const es2020_sharedmemory_1 = require("./es2020.sharedmemory");
|
||||
const es2020_string_1 = require("./es2020.string");
|
||||
const es2020_symbol_wellknown_1 = require("./es2020.symbol.wellknown");
|
||||
const es2021_1 = require("./es2021");
|
||||
const es2021_full_1 = require("./es2021.full");
|
||||
const es2021_intl_1 = require("./es2021.intl");
|
||||
const es2021_promise_1 = require("./es2021.promise");
|
||||
const es2021_string_1 = require("./es2021.string");
|
||||
const es2021_weakref_1 = require("./es2021.weakref");
|
||||
const es2022_1 = require("./es2022");
|
||||
const es2022_array_1 = require("./es2022.array");
|
||||
const es2022_error_1 = require("./es2022.error");
|
||||
const es2022_full_1 = require("./es2022.full");
|
||||
const es2022_intl_1 = require("./es2022.intl");
|
||||
const es2022_object_1 = require("./es2022.object");
|
||||
const es2022_regexp_1 = require("./es2022.regexp");
|
||||
const es2022_sharedmemory_1 = require("./es2022.sharedmemory");
|
||||
const es2022_string_1 = require("./es2022.string");
|
||||
const es2023_1 = require("./es2023");
|
||||
const es2023_array_1 = require("./es2023.array");
|
||||
const es2023_collection_1 = require("./es2023.collection");
|
||||
const es2023_full_1 = require("./es2023.full");
|
||||
const es2023_intl_1 = require("./es2023.intl");
|
||||
const esnext_1 = require("./esnext");
|
||||
const esnext_array_1 = require("./esnext.array");
|
||||
const esnext_asynciterable_1 = require("./esnext.asynciterable");
|
||||
const esnext_bigint_1 = require("./esnext.bigint");
|
||||
const esnext_collection_1 = require("./esnext.collection");
|
||||
const esnext_decorators_1 = require("./esnext.decorators");
|
||||
const esnext_disposable_1 = require("./esnext.disposable");
|
||||
const esnext_full_1 = require("./esnext.full");
|
||||
const esnext_intl_1 = require("./esnext.intl");
|
||||
const esnext_iterator_1 = require("./esnext.iterator");
|
||||
const esnext_object_1 = require("./esnext.object");
|
||||
const esnext_promise_1 = require("./esnext.promise");
|
||||
const esnext_regexp_1 = require("./esnext.regexp");
|
||||
const esnext_string_1 = require("./esnext.string");
|
||||
const esnext_symbol_1 = require("./esnext.symbol");
|
||||
const esnext_weakref_1 = require("./esnext.weakref");
|
||||
const lib_1 = require("./lib");
|
||||
const scripthost_1 = require("./scripthost");
|
||||
const webworker_1 = require("./webworker");
|
||||
const webworker_asynciterable_1 = require("./webworker.asynciterable");
|
||||
const webworker_importscripts_1 = require("./webworker.importscripts");
|
||||
const webworker_iterable_1 = require("./webworker.iterable");
|
||||
const lib = {
|
||||
decorators: decorators_1.decorators,
|
||||
'decorators.legacy': decorators_legacy_1.decorators_legacy,
|
||||
dom: dom_1.dom,
|
||||
'dom.asynciterable': dom_asynciterable_1.dom_asynciterable,
|
||||
'dom.iterable': dom_iterable_1.dom_iterable,
|
||||
es5: es5_1.es5,
|
||||
es6: es6_1.es6,
|
||||
es7: es7_1.es7,
|
||||
es2015: es2015_1.es2015,
|
||||
'es2015.collection': es2015_collection_1.es2015_collection,
|
||||
'es2015.core': es2015_core_1.es2015_core,
|
||||
'es2015.generator': es2015_generator_1.es2015_generator,
|
||||
'es2015.iterable': es2015_iterable_1.es2015_iterable,
|
||||
'es2015.promise': es2015_promise_1.es2015_promise,
|
||||
'es2015.proxy': es2015_proxy_1.es2015_proxy,
|
||||
'es2015.reflect': es2015_reflect_1.es2015_reflect,
|
||||
'es2015.symbol': es2015_symbol_1.es2015_symbol,
|
||||
'es2015.symbol.wellknown': es2015_symbol_wellknown_1.es2015_symbol_wellknown,
|
||||
es2016: es2016_1.es2016,
|
||||
'es2016.array.include': es2016_array_include_1.es2016_array_include,
|
||||
'es2016.full': es2016_full_1.es2016_full,
|
||||
'es2016.intl': es2016_intl_1.es2016_intl,
|
||||
es2017: es2017_1.es2017,
|
||||
'es2017.date': es2017_date_1.es2017_date,
|
||||
'es2017.full': es2017_full_1.es2017_full,
|
||||
'es2017.intl': es2017_intl_1.es2017_intl,
|
||||
'es2017.object': es2017_object_1.es2017_object,
|
||||
'es2017.sharedmemory': es2017_sharedmemory_1.es2017_sharedmemory,
|
||||
'es2017.string': es2017_string_1.es2017_string,
|
||||
'es2017.typedarrays': es2017_typedarrays_1.es2017_typedarrays,
|
||||
es2018: es2018_1.es2018,
|
||||
'es2018.asyncgenerator': es2018_asyncgenerator_1.es2018_asyncgenerator,
|
||||
'es2018.asynciterable': es2018_asynciterable_1.es2018_asynciterable,
|
||||
'es2018.full': es2018_full_1.es2018_full,
|
||||
'es2018.intl': es2018_intl_1.es2018_intl,
|
||||
'es2018.promise': es2018_promise_1.es2018_promise,
|
||||
'es2018.regexp': es2018_regexp_1.es2018_regexp,
|
||||
es2019: es2019_1.es2019,
|
||||
'es2019.array': es2019_array_1.es2019_array,
|
||||
'es2019.full': es2019_full_1.es2019_full,
|
||||
'es2019.intl': es2019_intl_1.es2019_intl,
|
||||
'es2019.object': es2019_object_1.es2019_object,
|
||||
'es2019.string': es2019_string_1.es2019_string,
|
||||
'es2019.symbol': es2019_symbol_1.es2019_symbol,
|
||||
es2020: es2020_1.es2020,
|
||||
'es2020.bigint': es2020_bigint_1.es2020_bigint,
|
||||
'es2020.date': es2020_date_1.es2020_date,
|
||||
'es2020.full': es2020_full_1.es2020_full,
|
||||
'es2020.intl': es2020_intl_1.es2020_intl,
|
||||
'es2020.number': es2020_number_1.es2020_number,
|
||||
'es2020.promise': es2020_promise_1.es2020_promise,
|
||||
'es2020.sharedmemory': es2020_sharedmemory_1.es2020_sharedmemory,
|
||||
'es2020.string': es2020_string_1.es2020_string,
|
||||
'es2020.symbol.wellknown': es2020_symbol_wellknown_1.es2020_symbol_wellknown,
|
||||
es2021: es2021_1.es2021,
|
||||
'es2021.full': es2021_full_1.es2021_full,
|
||||
'es2021.intl': es2021_intl_1.es2021_intl,
|
||||
'es2021.promise': es2021_promise_1.es2021_promise,
|
||||
'es2021.string': es2021_string_1.es2021_string,
|
||||
'es2021.weakref': es2021_weakref_1.es2021_weakref,
|
||||
es2022: es2022_1.es2022,
|
||||
'es2022.array': es2022_array_1.es2022_array,
|
||||
'es2022.error': es2022_error_1.es2022_error,
|
||||
'es2022.full': es2022_full_1.es2022_full,
|
||||
'es2022.intl': es2022_intl_1.es2022_intl,
|
||||
'es2022.object': es2022_object_1.es2022_object,
|
||||
'es2022.regexp': es2022_regexp_1.es2022_regexp,
|
||||
'es2022.sharedmemory': es2022_sharedmemory_1.es2022_sharedmemory,
|
||||
'es2022.string': es2022_string_1.es2022_string,
|
||||
es2023: es2023_1.es2023,
|
||||
'es2023.array': es2023_array_1.es2023_array,
|
||||
'es2023.collection': es2023_collection_1.es2023_collection,
|
||||
'es2023.full': es2023_full_1.es2023_full,
|
||||
'es2023.intl': es2023_intl_1.es2023_intl,
|
||||
esnext: esnext_1.esnext,
|
||||
'esnext.array': esnext_array_1.esnext_array,
|
||||
'esnext.asynciterable': esnext_asynciterable_1.esnext_asynciterable,
|
||||
'esnext.bigint': esnext_bigint_1.esnext_bigint,
|
||||
'esnext.collection': esnext_collection_1.esnext_collection,
|
||||
'esnext.decorators': esnext_decorators_1.esnext_decorators,
|
||||
'esnext.disposable': esnext_disposable_1.esnext_disposable,
|
||||
'esnext.full': esnext_full_1.esnext_full,
|
||||
'esnext.intl': esnext_intl_1.esnext_intl,
|
||||
'esnext.iterator': esnext_iterator_1.esnext_iterator,
|
||||
'esnext.object': esnext_object_1.esnext_object,
|
||||
'esnext.promise': esnext_promise_1.esnext_promise,
|
||||
'esnext.regexp': esnext_regexp_1.esnext_regexp,
|
||||
'esnext.string': esnext_string_1.esnext_string,
|
||||
'esnext.symbol': esnext_symbol_1.esnext_symbol,
|
||||
'esnext.weakref': esnext_weakref_1.esnext_weakref,
|
||||
lib: lib_1.lib,
|
||||
scripthost: scripthost_1.scripthost,
|
||||
webworker: webworker_1.webworker,
|
||||
'webworker.asynciterable': webworker_asynciterable_1.webworker_asynciterable,
|
||||
'webworker.importscripts': webworker_importscripts_1.webworker_importscripts,
|
||||
'webworker.iterable': webworker_iterable_1.webworker_iterable,
|
||||
};
|
||||
exports.lib = lib;
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lib/index.ts"],"names":[],"mappings":"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"}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
import type { Lib, TSESTree } from '@typescript-eslint/types';
|
||||
import type { Scope } from '../scope';
|
||||
import type { ScopeManager } from '../ScopeManager';
|
||||
import type { ReferenceImplicitGlobal } from './Reference';
|
||||
import type { VisitorOptions } from './Visitor';
|
||||
import { Visitor } from './Visitor';
|
||||
interface ReferencerOptions extends VisitorOptions {
|
||||
jsxFragmentName: string | null;
|
||||
jsxPragma: string | null;
|
||||
lib: Lib[];
|
||||
}
|
||||
declare class Referencer extends Visitor {
|
||||
#private;
|
||||
readonly scopeManager: ScopeManager;
|
||||
constructor(options: ReferencerOptions, scopeManager: ScopeManager);
|
||||
private populateGlobalsFromLib;
|
||||
close(node: TSESTree.Node): void;
|
||||
currentScope(): Scope;
|
||||
currentScope(throwOnNull: true): Scope | null;
|
||||
referencingDefaultValue(pattern: TSESTree.Identifier, assignments: (TSESTree.AssignmentExpression | TSESTree.AssignmentPattern)[], maybeImplicitGlobal: ReferenceImplicitGlobal | null, init: boolean): void;
|
||||
/**
|
||||
* Searches for a variable named "name" in the upper scopes and adds a pseudo-reference from itself to itself
|
||||
*/
|
||||
private referenceInSomeUpperScope;
|
||||
private referenceJsxFragment;
|
||||
private referenceJsxPragma;
|
||||
protected visitClass(node: TSESTree.ClassDeclaration | TSESTree.ClassExpression): void;
|
||||
protected visitForIn(node: TSESTree.ForInStatement | TSESTree.ForOfStatement): void;
|
||||
protected visitFunction(node: TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclaration | TSESTree.FunctionExpression | TSESTree.TSDeclareFunction | TSESTree.TSEmptyBodyFunctionExpression): void;
|
||||
protected visitFunctionParameterTypeAnnotation(node: TSESTree.Parameter): void;
|
||||
protected visitProperty(node: TSESTree.Property): void;
|
||||
protected visitType(node: TSESTree.Node | null | undefined): void;
|
||||
protected visitTypeAssertion(node: TSESTree.TSAsExpression | TSESTree.TSSatisfiesExpression | TSESTree.TSTypeAssertion): void;
|
||||
protected ArrowFunctionExpression(node: TSESTree.ArrowFunctionExpression): void;
|
||||
protected AssignmentExpression(node: TSESTree.AssignmentExpression): void;
|
||||
protected BlockStatement(node: TSESTree.BlockStatement): void;
|
||||
protected BreakStatement(): void;
|
||||
protected CallExpression(node: TSESTree.CallExpression): void;
|
||||
protected CatchClause(node: TSESTree.CatchClause): void;
|
||||
protected ClassDeclaration(node: TSESTree.ClassDeclaration): void;
|
||||
protected ClassExpression(node: TSESTree.ClassExpression): void;
|
||||
protected ContinueStatement(): void;
|
||||
protected ExportAllDeclaration(): void;
|
||||
protected ExportDefaultDeclaration(node: TSESTree.ExportDefaultDeclaration): void;
|
||||
protected ExportNamedDeclaration(node: TSESTree.ExportNamedDeclaration): void;
|
||||
protected ForInStatement(node: TSESTree.ForInStatement): void;
|
||||
protected ForOfStatement(node: TSESTree.ForOfStatement): void;
|
||||
protected ForStatement(node: TSESTree.ForStatement): void;
|
||||
protected FunctionDeclaration(node: TSESTree.FunctionDeclaration): void;
|
||||
protected FunctionExpression(node: TSESTree.FunctionExpression): void;
|
||||
protected Identifier(node: TSESTree.Identifier): void;
|
||||
protected ImportAttribute(): void;
|
||||
protected ImportDeclaration(node: TSESTree.ImportDeclaration): void;
|
||||
protected JSXAttribute(node: TSESTree.JSXAttribute): void;
|
||||
protected JSXClosingElement(): void;
|
||||
protected JSXFragment(node: TSESTree.JSXFragment): void;
|
||||
protected JSXIdentifier(node: TSESTree.JSXIdentifier): void;
|
||||
protected JSXMemberExpression(node: TSESTree.JSXMemberExpression): void;
|
||||
protected JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
|
||||
protected LabeledStatement(node: TSESTree.LabeledStatement): void;
|
||||
protected MemberExpression(node: TSESTree.MemberExpression): void;
|
||||
protected MetaProperty(): void;
|
||||
protected NewExpression(node: TSESTree.NewExpression): void;
|
||||
protected PrivateIdentifier(): void;
|
||||
protected Program(node: TSESTree.Program): void;
|
||||
protected Property(node: TSESTree.Property): void;
|
||||
protected SwitchStatement(node: TSESTree.SwitchStatement): void;
|
||||
protected TaggedTemplateExpression(node: TSESTree.TaggedTemplateExpression): void;
|
||||
protected TSAsExpression(node: TSESTree.TSAsExpression): void;
|
||||
protected TSDeclareFunction(node: TSESTree.TSDeclareFunction): void;
|
||||
protected TSEmptyBodyFunctionExpression(node: TSESTree.TSEmptyBodyFunctionExpression): void;
|
||||
protected TSEnumDeclaration(node: TSESTree.TSEnumDeclaration): void;
|
||||
protected TSExportAssignment(node: TSESTree.TSExportAssignment): void;
|
||||
protected TSImportEqualsDeclaration(node: TSESTree.TSImportEqualsDeclaration): void;
|
||||
protected TSInstantiationExpression(node: TSESTree.TSInstantiationExpression): void;
|
||||
protected TSInterfaceDeclaration(node: TSESTree.TSInterfaceDeclaration): void;
|
||||
protected TSModuleDeclaration(node: TSESTree.TSModuleDeclaration): void;
|
||||
protected TSSatisfiesExpression(node: TSESTree.TSSatisfiesExpression): void;
|
||||
protected TSTypeAliasDeclaration(node: TSESTree.TSTypeAliasDeclaration): void;
|
||||
protected TSTypeAssertion(node: TSESTree.TSTypeAssertion): void;
|
||||
protected UpdateExpression(node: TSESTree.UpdateExpression): void;
|
||||
protected VariableDeclaration(node: TSESTree.VariableDeclaration): void;
|
||||
protected WithStatement(node: TSESTree.WithStatement): void;
|
||||
private visitExpressionTarget;
|
||||
}
|
||||
export { Referencer, type ReferencerOptions };
|
||||
//# sourceMappingURL=Referencer.d.ts.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"Referencer.d.ts","sourceRoot":"","sources":["../../src/referencer/Referencer.ts"],"names":[],"mappings":"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"}
|
||||
+540
@@ -0,0 +1,540 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Referencer = void 0;
|
||||
const types_1 = require("@typescript-eslint/types");
|
||||
const assert_1 = require("../assert");
|
||||
const definition_1 = require("../definition");
|
||||
const lib_1 = require("../lib");
|
||||
const ClassVisitor_1 = require("./ClassVisitor");
|
||||
const ExportVisitor_1 = require("./ExportVisitor");
|
||||
const ImportVisitor_1 = require("./ImportVisitor");
|
||||
const PatternVisitor_1 = require("./PatternVisitor");
|
||||
const Reference_1 = require("./Reference");
|
||||
const TypeVisitor_1 = require("./TypeVisitor");
|
||||
const Visitor_1 = require("./Visitor");
|
||||
// Referencing variables and creating bindings.
|
||||
class Referencer extends Visitor_1.Visitor {
|
||||
#hasReferencedJsxFactory = false;
|
||||
#hasReferencedJsxFragmentFactory = false;
|
||||
#jsxFragmentName;
|
||||
#jsxPragma;
|
||||
#lib;
|
||||
scopeManager;
|
||||
constructor(options, scopeManager) {
|
||||
super(options);
|
||||
this.scopeManager = scopeManager;
|
||||
this.#jsxPragma = options.jsxPragma;
|
||||
this.#jsxFragmentName = options.jsxFragmentName;
|
||||
this.#lib = options.lib;
|
||||
}
|
||||
populateGlobalsFromLib(globalScope) {
|
||||
for (const lib of this.#lib) {
|
||||
const variables = lib_1.lib[lib];
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
/* istanbul ignore if */ if (!variables) {
|
||||
throw new Error(`Invalid value for lib provided: ${lib}`);
|
||||
}
|
||||
for (const [name, variable] of Object.entries(variables)) {
|
||||
globalScope.defineImplicitVariable(name, variable);
|
||||
}
|
||||
}
|
||||
// for const assertions (`{} as const` / `<const>{}`)
|
||||
globalScope.defineImplicitVariable('const', {
|
||||
eslintImplicitGlobalSetting: 'readonly',
|
||||
isTypeVariable: true,
|
||||
isValueVariable: false,
|
||||
});
|
||||
}
|
||||
close(node) {
|
||||
while (this.currentScope(true) && node === this.currentScope().block) {
|
||||
this.scopeManager.currentScope = this.currentScope().close(this.scopeManager);
|
||||
}
|
||||
}
|
||||
currentScope(dontThrowOnNull) {
|
||||
if (!dontThrowOnNull) {
|
||||
(0, assert_1.assert)(this.scopeManager.currentScope, 'aaa');
|
||||
}
|
||||
return this.scopeManager.currentScope;
|
||||
}
|
||||
referencingDefaultValue(pattern, assignments, maybeImplicitGlobal, init) {
|
||||
assignments.forEach(assignment => {
|
||||
this.currentScope().referenceValue(pattern, Reference_1.ReferenceFlag.Write, assignment.right, maybeImplicitGlobal, init);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Searches for a variable named "name" in the upper scopes and adds a pseudo-reference from itself to itself
|
||||
*/
|
||||
referenceInSomeUpperScope(name) {
|
||||
let scope = this.scopeManager.currentScope;
|
||||
while (scope) {
|
||||
const variable = scope.set.get(name);
|
||||
if (!variable) {
|
||||
scope = scope.upper;
|
||||
continue;
|
||||
}
|
||||
scope.referenceValue(variable.identifiers[0]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
referenceJsxFragment() {
|
||||
if (this.#jsxFragmentName == null ||
|
||||
this.#hasReferencedJsxFragmentFactory) {
|
||||
return;
|
||||
}
|
||||
this.#hasReferencedJsxFragmentFactory = this.referenceInSomeUpperScope(this.#jsxFragmentName);
|
||||
}
|
||||
referenceJsxPragma() {
|
||||
if (this.#jsxPragma == null || this.#hasReferencedJsxFactory) {
|
||||
return;
|
||||
}
|
||||
this.#hasReferencedJsxFactory = this.referenceInSomeUpperScope(this.#jsxPragma);
|
||||
}
|
||||
///////////////////
|
||||
// Visit helpers //
|
||||
///////////////////
|
||||
visitClass(node) {
|
||||
ClassVisitor_1.ClassVisitor.visit(this, node);
|
||||
}
|
||||
visitForIn(node) {
|
||||
if (node.left.type === types_1.AST_NODE_TYPES.VariableDeclaration &&
|
||||
node.left.kind !== 'var') {
|
||||
this.scopeManager.nestForScope(node);
|
||||
}
|
||||
if (node.left.type === types_1.AST_NODE_TYPES.VariableDeclaration) {
|
||||
this.visit(node.left);
|
||||
this.visitPattern(node.left.declarations[0].id, pattern => {
|
||||
this.currentScope().referenceValue(pattern, Reference_1.ReferenceFlag.Write, node.right, null, true);
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.visitPattern(node.left, (pattern, info) => {
|
||||
const maybeImplicitGlobal = !this.currentScope().isStrict
|
||||
? {
|
||||
node,
|
||||
pattern,
|
||||
}
|
||||
: null;
|
||||
this.referencingDefaultValue(pattern, info.assignments, maybeImplicitGlobal, false);
|
||||
this.currentScope().referenceValue(pattern, Reference_1.ReferenceFlag.Write, node.right, maybeImplicitGlobal, false);
|
||||
}, { processRightHandNodes: true });
|
||||
}
|
||||
this.visit(node.right);
|
||||
this.visit(node.body);
|
||||
this.close(node);
|
||||
}
|
||||
visitFunction(node) {
|
||||
// FunctionDeclaration name is defined in upper scope
|
||||
// NOTE: Not referring variableScope. It is intended.
|
||||
// Since
|
||||
// in ES5, FunctionDeclaration should be in FunctionBody.
|
||||
// in ES6, FunctionDeclaration should be block scoped.
|
||||
if (node.type === types_1.AST_NODE_TYPES.FunctionExpression) {
|
||||
if (node.id) {
|
||||
// FunctionExpression with name creates its special scope;
|
||||
// FunctionExpressionNameScope.
|
||||
this.scopeManager.nestFunctionExpressionNameScope(node);
|
||||
}
|
||||
}
|
||||
else if (node.id) {
|
||||
// id is defined in upper scope
|
||||
this.currentScope().defineIdentifier(node.id, new definition_1.FunctionNameDefinition(node.id, node));
|
||||
}
|
||||
// Consider this function is in the MethodDefinition.
|
||||
this.scopeManager.nestFunctionScope(node, false);
|
||||
// Process parameter declarations.
|
||||
for (const param of node.params) {
|
||||
this.visitPattern(param, (pattern, info) => {
|
||||
this.currentScope().defineIdentifier(pattern, new definition_1.ParameterDefinition(pattern, node, info.rest));
|
||||
this.referencingDefaultValue(pattern, info.assignments, null, true);
|
||||
}, { processRightHandNodes: true });
|
||||
this.visitFunctionParameterTypeAnnotation(param);
|
||||
param.decorators.forEach(d => this.visit(d));
|
||||
}
|
||||
this.visitType(node.returnType);
|
||||
this.visitType(node.typeParameters);
|
||||
// In TypeScript there are a number of function-like constructs which have no body,
|
||||
// so check it exists before traversing
|
||||
if (node.body) {
|
||||
// Skip BlockStatement to prevent creating BlockStatement scope.
|
||||
if (node.body.type === types_1.AST_NODE_TYPES.BlockStatement) {
|
||||
this.visitChildren(node.body);
|
||||
}
|
||||
else {
|
||||
this.visit(node.body);
|
||||
}
|
||||
}
|
||||
this.close(node);
|
||||
}
|
||||
visitFunctionParameterTypeAnnotation(node) {
|
||||
switch (node.type) {
|
||||
case types_1.AST_NODE_TYPES.AssignmentPattern:
|
||||
this.visitType(node.left.typeAnnotation);
|
||||
break;
|
||||
case types_1.AST_NODE_TYPES.TSParameterProperty:
|
||||
this.visitFunctionParameterTypeAnnotation(node.parameter);
|
||||
break;
|
||||
default:
|
||||
this.visitType(node.typeAnnotation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
visitProperty(node) {
|
||||
if (node.computed) {
|
||||
this.visit(node.key);
|
||||
}
|
||||
this.visit(node.value);
|
||||
}
|
||||
visitType(node) {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
TypeVisitor_1.TypeVisitor.visit(this, node);
|
||||
}
|
||||
visitTypeAssertion(node) {
|
||||
this.visit(node.expression);
|
||||
this.visitType(node.typeAnnotation);
|
||||
}
|
||||
/////////////////////
|
||||
// Visit selectors //
|
||||
/////////////////////
|
||||
ArrowFunctionExpression(node) {
|
||||
this.visitFunction(node);
|
||||
}
|
||||
AssignmentExpression(node) {
|
||||
const left = this.visitExpressionTarget(node.left);
|
||||
if (PatternVisitor_1.PatternVisitor.isPattern(left)) {
|
||||
if (node.operator === '=') {
|
||||
this.visitPattern(left, (pattern, info) => {
|
||||
const maybeImplicitGlobal = !this.currentScope().isStrict
|
||||
? {
|
||||
node,
|
||||
pattern,
|
||||
}
|
||||
: null;
|
||||
this.referencingDefaultValue(pattern, info.assignments, maybeImplicitGlobal, false);
|
||||
this.currentScope().referenceValue(pattern, Reference_1.ReferenceFlag.Write, node.right, maybeImplicitGlobal, false);
|
||||
}, { processRightHandNodes: true });
|
||||
}
|
||||
else if (left.type === types_1.AST_NODE_TYPES.Identifier) {
|
||||
this.currentScope().referenceValue(left, Reference_1.ReferenceFlag.ReadWrite, node.right);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.visit(left);
|
||||
}
|
||||
this.visit(node.right);
|
||||
}
|
||||
BlockStatement(node) {
|
||||
this.scopeManager.nestBlockScope(node);
|
||||
this.visitChildren(node);
|
||||
this.close(node);
|
||||
}
|
||||
BreakStatement() {
|
||||
// don't reference the break statement's label
|
||||
}
|
||||
CallExpression(node) {
|
||||
this.visitChildren(node, ['typeArguments']);
|
||||
this.visitType(node.typeArguments);
|
||||
}
|
||||
CatchClause(node) {
|
||||
this.scopeManager.nestCatchScope(node);
|
||||
if (node.param) {
|
||||
const param = node.param;
|
||||
this.visitPattern(param, (pattern, info) => {
|
||||
this.currentScope().defineIdentifier(pattern, new definition_1.CatchClauseDefinition(param, node));
|
||||
this.referencingDefaultValue(pattern, info.assignments, null, true);
|
||||
}, { processRightHandNodes: true });
|
||||
}
|
||||
this.visit(node.body);
|
||||
this.close(node);
|
||||
}
|
||||
ClassDeclaration(node) {
|
||||
this.visitClass(node);
|
||||
}
|
||||
ClassExpression(node) {
|
||||
this.visitClass(node);
|
||||
}
|
||||
ContinueStatement() {
|
||||
// don't reference the continue statement's label
|
||||
}
|
||||
ExportAllDeclaration() {
|
||||
// this defines no local variables
|
||||
}
|
||||
ExportDefaultDeclaration(node) {
|
||||
if (node.declaration.type === types_1.AST_NODE_TYPES.Identifier) {
|
||||
ExportVisitor_1.ExportVisitor.visit(this, node);
|
||||
}
|
||||
else {
|
||||
this.visit(node.declaration);
|
||||
}
|
||||
}
|
||||
ExportNamedDeclaration(node) {
|
||||
if (node.declaration) {
|
||||
this.visit(node.declaration);
|
||||
}
|
||||
else {
|
||||
ExportVisitor_1.ExportVisitor.visit(this, node);
|
||||
}
|
||||
}
|
||||
ForInStatement(node) {
|
||||
this.visitForIn(node);
|
||||
}
|
||||
ForOfStatement(node) {
|
||||
this.visitForIn(node);
|
||||
}
|
||||
ForStatement(node) {
|
||||
// Create ForStatement declaration.
|
||||
// NOTE: In ES6, ForStatement dynamically generates per iteration environment. However, this is
|
||||
// a static analyzer, we only generate one scope for ForStatement.
|
||||
if (node.init &&
|
||||
node.init.type === types_1.AST_NODE_TYPES.VariableDeclaration &&
|
||||
node.init.kind !== 'var') {
|
||||
this.scopeManager.nestForScope(node);
|
||||
}
|
||||
this.visitChildren(node);
|
||||
this.close(node);
|
||||
}
|
||||
FunctionDeclaration(node) {
|
||||
this.visitFunction(node);
|
||||
}
|
||||
FunctionExpression(node) {
|
||||
this.visitFunction(node);
|
||||
}
|
||||
Identifier(node) {
|
||||
this.currentScope().referenceValue(node);
|
||||
this.visitType(node.typeAnnotation);
|
||||
}
|
||||
ImportAttribute() {
|
||||
// import assertions are module metadata and thus have no variables to reference
|
||||
}
|
||||
ImportDeclaration(node) {
|
||||
(0, assert_1.assert)(this.scopeManager.isModule(), 'ImportDeclaration should appear when the mode is ES6 and in the module context.');
|
||||
ImportVisitor_1.ImportVisitor.visit(this, node);
|
||||
}
|
||||
JSXAttribute(node) {
|
||||
this.visit(node.value);
|
||||
}
|
||||
JSXClosingElement() {
|
||||
// should not be counted as a reference
|
||||
}
|
||||
JSXFragment(node) {
|
||||
this.referenceJsxPragma();
|
||||
this.referenceJsxFragment();
|
||||
this.visitChildren(node);
|
||||
}
|
||||
JSXIdentifier(node) {
|
||||
this.currentScope().referenceValue(node);
|
||||
}
|
||||
JSXMemberExpression(node) {
|
||||
if (node.object.type !== types_1.AST_NODE_TYPES.JSXIdentifier ||
|
||||
node.object.name !== 'this') {
|
||||
this.visit(node.object);
|
||||
}
|
||||
// we don't ever reference the property as it's always going to be a property on the thing
|
||||
}
|
||||
JSXOpeningElement(node) {
|
||||
this.referenceJsxPragma();
|
||||
if (node.name.type === types_1.AST_NODE_TYPES.JSXIdentifier) {
|
||||
if (node.name.name[0].toUpperCase() === node.name.name[0] ||
|
||||
node.name.name === 'this') {
|
||||
// lower cased component names are always treated as "intrinsic" names, and are converted to a string,
|
||||
// not a variable by JSX transforms:
|
||||
// <div /> => React.createElement("div", null)
|
||||
// the only case we want to visit a lower-cased component has its name as "this",
|
||||
this.visit(node.name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.visit(node.name);
|
||||
}
|
||||
this.visitType(node.typeArguments);
|
||||
for (const attr of node.attributes) {
|
||||
this.visit(attr);
|
||||
}
|
||||
}
|
||||
LabeledStatement(node) {
|
||||
this.visit(node.body);
|
||||
}
|
||||
MemberExpression(node) {
|
||||
this.visit(node.object);
|
||||
if (node.computed) {
|
||||
this.visit(node.property);
|
||||
}
|
||||
}
|
||||
MetaProperty() {
|
||||
// meta properties all builtin globals
|
||||
}
|
||||
NewExpression(node) {
|
||||
this.visitChildren(node, ['typeArguments']);
|
||||
this.visitType(node.typeArguments);
|
||||
}
|
||||
PrivateIdentifier() {
|
||||
// private identifiers are members on classes and thus have no variables to reference
|
||||
}
|
||||
Program(node) {
|
||||
const globalScope = this.scopeManager.nestGlobalScope(node);
|
||||
this.populateGlobalsFromLib(globalScope);
|
||||
if (this.scopeManager.isGlobalReturn()) {
|
||||
// Force strictness of GlobalScope to false when using node.js scope.
|
||||
this.currentScope().isStrict = false;
|
||||
this.scopeManager.nestFunctionScope(node, false);
|
||||
}
|
||||
if (this.scopeManager.isModule()) {
|
||||
this.scopeManager.nestModuleScope(node);
|
||||
}
|
||||
if (this.scopeManager.isImpliedStrict()) {
|
||||
this.currentScope().isStrict = true;
|
||||
}
|
||||
this.visitChildren(node);
|
||||
this.close(node);
|
||||
}
|
||||
Property(node) {
|
||||
this.visitProperty(node);
|
||||
}
|
||||
SwitchStatement(node) {
|
||||
this.visit(node.discriminant);
|
||||
this.scopeManager.nestSwitchScope(node);
|
||||
for (const switchCase of node.cases) {
|
||||
this.visit(switchCase);
|
||||
}
|
||||
this.close(node);
|
||||
}
|
||||
TaggedTemplateExpression(node) {
|
||||
this.visit(node.tag);
|
||||
this.visit(node.quasi);
|
||||
this.visitType(node.typeArguments);
|
||||
}
|
||||
TSAsExpression(node) {
|
||||
this.visitTypeAssertion(node);
|
||||
}
|
||||
TSDeclareFunction(node) {
|
||||
this.visitFunction(node);
|
||||
}
|
||||
TSEmptyBodyFunctionExpression(node) {
|
||||
this.visitFunction(node);
|
||||
}
|
||||
TSEnumDeclaration(node) {
|
||||
this.currentScope().defineIdentifier(node.id, new definition_1.TSEnumNameDefinition(node.id, node));
|
||||
// enum members can be referenced within the enum body
|
||||
this.scopeManager.nestTSEnumScope(node);
|
||||
for (const member of node.body.members) {
|
||||
// TS resolves literal named members to be actual names
|
||||
// enum Foo {
|
||||
// 'a' = 1,
|
||||
// b = a, // this references the 'a' member
|
||||
// }
|
||||
if (member.id.type === types_1.AST_NODE_TYPES.Literal &&
|
||||
typeof member.id.value === 'string') {
|
||||
const name = member.id;
|
||||
this.currentScope().defineLiteralIdentifier(name, new definition_1.TSEnumMemberDefinition(name, member));
|
||||
}
|
||||
else if (!member.computed &&
|
||||
member.id.type === types_1.AST_NODE_TYPES.Identifier) {
|
||||
this.currentScope().defineIdentifier(member.id, new definition_1.TSEnumMemberDefinition(member.id, member));
|
||||
}
|
||||
this.visit(member.initializer);
|
||||
}
|
||||
this.close(node);
|
||||
}
|
||||
TSExportAssignment(node) {
|
||||
if (node.expression.type === types_1.AST_NODE_TYPES.Identifier) {
|
||||
// this is a special case - you can `export = T` where `T` is a type OR a
|
||||
// value however `T[U]` is illegal when `T` is a type and `T.U` is illegal
|
||||
// when `T.U` is a type
|
||||
// i.e. if the expression is JUST an Identifier - it could be either ref
|
||||
// kind; otherwise the standard rules apply
|
||||
this.currentScope().referenceDualValueType(node.expression);
|
||||
}
|
||||
else {
|
||||
this.visit(node.expression);
|
||||
}
|
||||
}
|
||||
TSImportEqualsDeclaration(node) {
|
||||
this.currentScope().defineIdentifier(node.id, new definition_1.ImportBindingDefinition(node.id, node, node));
|
||||
if (node.moduleReference.type === types_1.AST_NODE_TYPES.TSQualifiedName) {
|
||||
let moduleIdentifier = node.moduleReference.left;
|
||||
while (moduleIdentifier.type === types_1.AST_NODE_TYPES.TSQualifiedName) {
|
||||
moduleIdentifier = moduleIdentifier.left;
|
||||
}
|
||||
this.visit(moduleIdentifier);
|
||||
}
|
||||
else {
|
||||
this.visit(node.moduleReference);
|
||||
}
|
||||
}
|
||||
TSInstantiationExpression(node) {
|
||||
this.visitChildren(node, ['typeArguments']);
|
||||
this.visitType(node.typeArguments);
|
||||
}
|
||||
TSInterfaceDeclaration(node) {
|
||||
this.visitType(node);
|
||||
}
|
||||
TSModuleDeclaration(node) {
|
||||
if (node.id.type === types_1.AST_NODE_TYPES.Identifier && node.kind !== 'global') {
|
||||
this.currentScope().defineIdentifier(node.id, new definition_1.TSModuleNameDefinition(node.id, node));
|
||||
}
|
||||
this.scopeManager.nestTSModuleScope(node);
|
||||
this.visit(node.body);
|
||||
this.close(node);
|
||||
}
|
||||
TSSatisfiesExpression(node) {
|
||||
this.visitTypeAssertion(node);
|
||||
}
|
||||
TSTypeAliasDeclaration(node) {
|
||||
this.visitType(node);
|
||||
}
|
||||
TSTypeAssertion(node) {
|
||||
this.visitTypeAssertion(node);
|
||||
}
|
||||
UpdateExpression(node) {
|
||||
const argument = this.visitExpressionTarget(node.argument);
|
||||
if (PatternVisitor_1.PatternVisitor.isPattern(argument)) {
|
||||
this.visitPattern(argument, pattern => {
|
||||
this.currentScope().referenceValue(pattern, Reference_1.ReferenceFlag.ReadWrite, null);
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.visitChildren(node);
|
||||
}
|
||||
}
|
||||
VariableDeclaration(node) {
|
||||
const variableTargetScope = node.kind === 'var'
|
||||
? this.currentScope().variableScope
|
||||
: this.currentScope();
|
||||
for (const decl of node.declarations) {
|
||||
const init = decl.init;
|
||||
this.visitPattern(decl.id, (pattern, info) => {
|
||||
variableTargetScope.defineIdentifier(pattern, new definition_1.VariableDefinition(pattern, decl, node));
|
||||
this.referencingDefaultValue(pattern, info.assignments, null, true);
|
||||
if (init) {
|
||||
this.currentScope().referenceValue(pattern, Reference_1.ReferenceFlag.Write, init, null, true);
|
||||
}
|
||||
}, { processRightHandNodes: true });
|
||||
this.visit(decl.init);
|
||||
this.visitType(decl.id.typeAnnotation);
|
||||
}
|
||||
}
|
||||
WithStatement(node) {
|
||||
this.visit(node.object);
|
||||
// Then nest scope for WithStatement.
|
||||
this.scopeManager.nestWithScope(node);
|
||||
this.visit(node.body);
|
||||
this.close(node);
|
||||
}
|
||||
visitExpressionTarget(left) {
|
||||
switch (left.type) {
|
||||
case types_1.AST_NODE_TYPES.TSAsExpression:
|
||||
case types_1.AST_NODE_TYPES.TSTypeAssertion:
|
||||
// explicitly visit the type annotation
|
||||
this.visitType(left.typeAnnotation);
|
||||
// intentional fallthrough
|
||||
case types_1.AST_NODE_TYPES.TSNonNullExpression:
|
||||
// unwrap the expression
|
||||
left = left.expression;
|
||||
}
|
||||
return left;
|
||||
}
|
||||
}
|
||||
exports.Referencer = Referencer;
|
||||
//# sourceMappingURL=Referencer.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+74
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"name": "@typescript-eslint/scope-manager",
|
||||
"version": "8.14.0",
|
||||
"description": "TypeScript scope analyser for ESLint",
|
||||
"files": [
|
||||
"dist",
|
||||
"package.json",
|
||||
"README.md",
|
||||
"LICENSE"
|
||||
],
|
||||
"type": "commonjs",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"types": "./dist/index.d.ts",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
|
||||
"directory": "packages/scope-manager"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
|
||||
},
|
||||
"homepage": "https://typescript-eslint.io/packages/scope-manager",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"eslint",
|
||||
"typescript",
|
||||
"estree"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "npx nx build",
|
||||
"clean": "npx nx clean",
|
||||
"clean-fixtures": "npx nx clean-fixtures",
|
||||
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
|
||||
"generate-lib": "npx nx generate-lib repo",
|
||||
"lint": "npx nx lint",
|
||||
"test": "npx nx test --code-coverage",
|
||||
"typecheck": "npx nx typecheck"
|
||||
},
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.14.0",
|
||||
"@typescript-eslint/visitor-keys": "8.14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jest/types": "29.6.3",
|
||||
"@types/glob": "*",
|
||||
"@typescript-eslint/typescript-estree": "8.14.0",
|
||||
"glob": "*",
|
||||
"jest-specific-snapshot": "*",
|
||||
"make-dir": "*",
|
||||
"prettier": "^3.2.5",
|
||||
"pretty-format": "*",
|
||||
"typescript": "*"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"typesVersions": {
|
||||
"<4.7": {
|
||||
"*": [
|
||||
"_ts4.3/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"name": "@typescript-eslint/type-utils",
|
||||
"version": "8.14.0",
|
||||
"description": "Type utilities for working with TypeScript + ESLint together",
|
||||
"files": [
|
||||
"dist",
|
||||
"_ts4.3",
|
||||
"package.json",
|
||||
"README.md",
|
||||
"LICENSE"
|
||||
],
|
||||
"type": "commonjs",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
|
||||
"directory": "packages/type-utils"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
|
||||
},
|
||||
"homepage": "https://typescript-eslint.io",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"eslint",
|
||||
"typescript",
|
||||
"estree"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc -b tsconfig.build.json",
|
||||
"postbuild": "downlevel-dts dist _ts4.3/dist --to=4.3",
|
||||
"clean": "tsc -b tsconfig.build.json --clean",
|
||||
"postclean": "rimraf dist && rimraf _ts3.4 && rimraf _ts4.3 && rimraf coverage",
|
||||
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
|
||||
"lint": "npx nx lint",
|
||||
"test": "jest --coverage",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@typescript-eslint/typescript-estree": "8.14.0",
|
||||
"@typescript-eslint/utils": "8.14.0",
|
||||
"debug": "^4.3.4",
|
||||
"ts-api-utils": "^1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jest/types": "29.6.3",
|
||||
"@typescript-eslint/parser": "8.14.0",
|
||||
"ajv": "^6.12.6",
|
||||
"downlevel-dts": "*",
|
||||
"jest": "29.7.0",
|
||||
"prettier": "^3.2.5",
|
||||
"rimraf": "*",
|
||||
"typescript": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"typesVersions": {
|
||||
"<4.7": {
|
||||
"*": [
|
||||
"_ts4.3/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
+2159
File diff suppressed because it is too large
Load Diff
+1
File diff suppressed because one or more lines are too long
+173
@@ -0,0 +1,173 @@
|
||||
import type * as TSESTree from './generated/ast-spec';
|
||||
declare module './generated/ast-spec' {
|
||||
interface BaseNode {
|
||||
parent: TSESTree.Node;
|
||||
}
|
||||
interface Program {
|
||||
/**
|
||||
* @remarks This never-used property exists only as a convenience for code that tries to access node parents repeatedly.
|
||||
*/
|
||||
parent?: never;
|
||||
}
|
||||
interface AccessorPropertyComputedName {
|
||||
parent: TSESTree.ClassBody;
|
||||
}
|
||||
interface AccessorPropertyNonComputedName {
|
||||
parent: TSESTree.ClassBody;
|
||||
}
|
||||
interface TSAbstractAccessorPropertyComputedName {
|
||||
parent: TSESTree.ClassBody;
|
||||
}
|
||||
interface TSAbstractAccessorPropertyNonComputedName {
|
||||
parent: TSESTree.ClassBody;
|
||||
}
|
||||
interface VariableDeclaratorDefiniteAssignment {
|
||||
parent: TSESTree.VariableDeclaration;
|
||||
}
|
||||
interface VariableDeclaratorMaybeInit {
|
||||
parent: TSESTree.VariableDeclaration;
|
||||
}
|
||||
interface VariableDeclaratorNoInit {
|
||||
parent: TSESTree.VariableDeclaration;
|
||||
}
|
||||
interface UsingInForOfDeclarator {
|
||||
parent: TSESTree.VariableDeclaration;
|
||||
}
|
||||
interface UsingInNormalContextDeclarator {
|
||||
parent: TSESTree.VariableDeclaration;
|
||||
}
|
||||
interface CatchClause {
|
||||
parent: TSESTree.TryStatement;
|
||||
}
|
||||
interface ClassBody {
|
||||
parent: TSESTree.ClassDeclaration | TSESTree.ClassExpression;
|
||||
}
|
||||
interface ImportAttribute {
|
||||
parent: TSESTree.ExportAllDeclaration | TSESTree.ExportNamedDeclaration | TSESTree.ImportDeclaration;
|
||||
}
|
||||
interface ImportDefaultSpecifier {
|
||||
parent: TSESTree.ImportDeclaration;
|
||||
}
|
||||
interface ImportNamespaceSpecifier {
|
||||
parent: TSESTree.ImportDeclaration;
|
||||
}
|
||||
interface ImportSpecifier {
|
||||
parent: TSESTree.ExportAllDeclaration | TSESTree.ExportNamedDeclaration | TSESTree.ImportDeclaration;
|
||||
}
|
||||
interface JSXAttribute {
|
||||
parent: TSESTree.JSXOpeningElement;
|
||||
}
|
||||
interface JSXClosingElement {
|
||||
parent: TSESTree.JSXElement;
|
||||
}
|
||||
interface JSXClosingFragment {
|
||||
parent: TSESTree.JSXFragment;
|
||||
}
|
||||
interface JSXOpeningElement {
|
||||
parent: TSESTree.JSXElement;
|
||||
}
|
||||
interface JSXOpeningFragment {
|
||||
parent: TSESTree.JSXFragment;
|
||||
}
|
||||
interface JSXSpreadAttribute {
|
||||
parent: TSESTree.JSXOpeningElement;
|
||||
}
|
||||
interface MethodDefinitionComputedName {
|
||||
parent: TSESTree.ClassBody;
|
||||
}
|
||||
interface MethodDefinitionNonComputedName {
|
||||
parent: TSESTree.ClassBody;
|
||||
}
|
||||
interface TSAbstractMethodDefinitionComputedName {
|
||||
parent: TSESTree.ClassBody;
|
||||
}
|
||||
interface TSAbstractMethodDefinitionNonComputedName {
|
||||
parent: TSESTree.ClassBody;
|
||||
}
|
||||
interface PropertyComputedName {
|
||||
parent: TSESTree.ObjectExpression | TSESTree.ObjectPattern;
|
||||
}
|
||||
interface PropertyNonComputedName {
|
||||
parent: TSESTree.ObjectExpression | TSESTree.ObjectPattern;
|
||||
}
|
||||
interface PropertyDefinitionComputedName {
|
||||
parent: TSESTree.ClassBody;
|
||||
}
|
||||
interface PropertyDefinitionNonComputedName {
|
||||
parent: TSESTree.ClassBody;
|
||||
}
|
||||
interface TSAbstractPropertyDefinitionComputedName {
|
||||
parent: TSESTree.ClassBody;
|
||||
}
|
||||
interface TSAbstractPropertyDefinitionNonComputedName {
|
||||
parent: TSESTree.ClassBody;
|
||||
}
|
||||
interface SpreadElement {
|
||||
parent: TSESTree.ArrayExpression | TSESTree.CallExpression | TSESTree.NewExpression | TSESTree.ObjectExpression;
|
||||
}
|
||||
interface StaticBlock {
|
||||
parent: TSESTree.ClassBody;
|
||||
}
|
||||
interface SwitchCase {
|
||||
parent: TSESTree.SwitchStatement;
|
||||
}
|
||||
interface TemplateElement {
|
||||
parent: TSESTree.TemplateLiteral | TSESTree.TSTemplateLiteralType;
|
||||
}
|
||||
interface TSCallSignatureDeclaration {
|
||||
parent: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral;
|
||||
}
|
||||
interface TSConstructSignatureDeclaration {
|
||||
parent: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral;
|
||||
}
|
||||
interface TSClassImplements {
|
||||
parent: TSESTree.ClassDeclaration | TSESTree.ClassExpression;
|
||||
}
|
||||
interface TSEnumBody {
|
||||
parent: TSESTree.TSEnumDeclaration;
|
||||
}
|
||||
interface TSEnumMemberComputedName {
|
||||
parent: TSESTree.TSEnumBody;
|
||||
}
|
||||
interface TSEnumMemberNonComputedName {
|
||||
parent: TSESTree.TSEnumBody;
|
||||
}
|
||||
interface TSIndexSignature {
|
||||
parent: TSESTree.ClassBody | TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral;
|
||||
}
|
||||
interface TSInterfaceBody {
|
||||
parent: TSESTree.TSInterfaceDeclaration;
|
||||
}
|
||||
interface TSInterfaceHeritage {
|
||||
parent: TSESTree.TSInterfaceBody;
|
||||
}
|
||||
interface TSMethodSignatureComputedName {
|
||||
parent: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral;
|
||||
}
|
||||
interface TSMethodSignatureNonComputedName {
|
||||
parent: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral;
|
||||
}
|
||||
interface TSModuleBlock {
|
||||
parent: TSESTree.TSModuleDeclaration;
|
||||
}
|
||||
interface TSParameterProperty {
|
||||
parent: TSESTree.FunctionLike;
|
||||
}
|
||||
interface TSPropertySignatureComputedName {
|
||||
parent: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral;
|
||||
}
|
||||
interface TSPropertySignatureNonComputedName {
|
||||
parent: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral;
|
||||
}
|
||||
interface TSTypeParameter {
|
||||
parent: TSESTree.TSInferType | TSESTree.TSMappedType | TSESTree.TSTypeParameterDeclaration;
|
||||
}
|
||||
interface ExportSpecifierWithIdentifierLocal {
|
||||
parent: TSESTree.ExportNamedDeclaration;
|
||||
}
|
||||
interface ExportSpecifierWithStringOrLiteralLocal {
|
||||
parent: TSESTree.ExportNamedDeclaration;
|
||||
}
|
||||
}
|
||||
export * as TSESTree from './generated/ast-spec';
|
||||
//# sourceMappingURL=ts-estree.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ts-estree.d.ts","sourceRoot":"","sources":["../src/ts-estree.ts"],"names":[],"mappings":"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"}
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ts-estree.js","sourceRoot":"","sources":["../src/ts-estree.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAkOA,iEAAiD"}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"name": "@typescript-eslint/types",
|
||||
"version": "8.14.0",
|
||||
"description": "Types for the TypeScript-ESTree AST spec",
|
||||
"files": [
|
||||
"dist",
|
||||
"_ts4.3",
|
||||
"package.json",
|
||||
"README.md",
|
||||
"LICENSE"
|
||||
],
|
||||
"type": "commonjs",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"types": "./dist/index.d.ts",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
|
||||
"directory": "packages/types"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
|
||||
},
|
||||
"homepage": "https://typescript-eslint.io",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"eslint",
|
||||
"typescript",
|
||||
"estree"
|
||||
],
|
||||
"scripts": {
|
||||
"copy-ast-spec": "tsx ./tools/copy-ast-spec.ts",
|
||||
"build": "tsc -b tsconfig.build.json",
|
||||
"postbuild": "downlevel-dts dist _ts4.3/dist --to=4.3",
|
||||
"clean": "tsc -b tsconfig.build.json --clean",
|
||||
"postclean": "rimraf dist && rimraf src/generated && rimraf _ts3.4 && rimraf _ts4.3 && rimraf coverage",
|
||||
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
|
||||
"generate-lib": "npx nx run scope-manager:generate-lib",
|
||||
"lint": "npx nx lint",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"nx": {
|
||||
"targets": {
|
||||
"copy-ast-spec": {
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
],
|
||||
"outputs": [
|
||||
"{projectRoot}/src/generated"
|
||||
],
|
||||
"cache": true
|
||||
},
|
||||
"build": {
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
"copy-ast-spec"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jest/types": "29.6.3",
|
||||
"downlevel-dts": "*",
|
||||
"prettier": "^3.2.5",
|
||||
"rimraf": "*",
|
||||
"tsx": "*",
|
||||
"typescript": "*"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"typesVersions": {
|
||||
"<4.7": {
|
||||
"*": [
|
||||
"_ts4.3/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EACV,aAAa,EACb,2BAA2B,EAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAoB,MAAM,EAAE,MAAM,aAAa,CAAC;AAmCtE,MAAM,WAAW,gBAAgB;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,kCAAkC,CAAC,EAAE,OAAO,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,wBAAwB,GAAG,EAAE,CAAC,sBAAsB,GAC1D,OAAO,CAMT;AAED,MAAM,WAAW,OAAO;IACtB,qBAAqB,EAAE,2BAA2B,CAAC;IACnD,qBAAqB,EAAE,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED,qBAAa,SAAS;;IACpB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAgB;IACpC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IAEvD;;;;;OAKG;gBACS,GAAG,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,gBAAgB;IAsZ1D,OAAO,CAAC,qBAAqB;IAsB7B,OAAO,CAAC,oCAAoC;IAe5C;;;;;OAKG;IACH,OAAO,CAAC,sBAAsB;IAiC9B,OAAO,CAAC,sBAAsB;IA4C9B;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAIpB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAItB;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAsB7B;;;;;OAKG;IACH,OAAO,CAAC,gDAAgD;IAexD;;;;OAIG;IACH,OAAO,CAAC,kDAAkD;IAmB1D;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;IA8BjB,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,+BAA+B;IAiDvC;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IA8BzB,OAAO,CAAC,sBAAsB;IAoC9B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IA09EnB,OAAO,CAAC,UAAU;IAelB,cAAc,IAAI,QAAQ,CAAC,OAAO;IAIlC;;;;OAIG;IACH,OAAO,CAAC,UAAU;IA0FlB;;;OAGG;IACH,OAAO,CAAC,UAAU;IAiFlB,UAAU,IAAI,OAAO;IAOrB;;OAEG;IACH,OAAO,CAAC,uBAAuB;CAYhC"}
|
||||
+2671
File diff suppressed because it is too large
Load Diff
+1
File diff suppressed because one or more lines are too long
+91
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"name": "@typescript-eslint/typescript-estree",
|
||||
"version": "8.14.0",
|
||||
"description": "A parser that converts TypeScript source code into an ESTree compatible form",
|
||||
"files": [
|
||||
"dist",
|
||||
"_ts4.3",
|
||||
"README.md",
|
||||
"LICENSE"
|
||||
],
|
||||
"type": "commonjs",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
},
|
||||
"./package.json": "./package.json",
|
||||
"./use-at-your-own-risk": {
|
||||
"types": "./dist/use-at-your-own-risk.d.ts",
|
||||
"default": "./dist/use-at-your-own-risk.js"
|
||||
}
|
||||
},
|
||||
"types": "./dist/index.d.ts",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
|
||||
"directory": "packages/typescript-estree"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
|
||||
},
|
||||
"homepage": "https://typescript-eslint.io/packages/typescript-estree",
|
||||
"license": "BSD-2-Clause",
|
||||
"keywords": [
|
||||
"ast",
|
||||
"estree",
|
||||
"ecmascript",
|
||||
"javascript",
|
||||
"typescript",
|
||||
"parser",
|
||||
"syntax"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc -b tsconfig.build.json",
|
||||
"postbuild": "downlevel-dts dist _ts4.3/dist --to=4.3",
|
||||
"clean": "tsc -b tsconfig.build.json --clean",
|
||||
"postclean": "rimraf dist && rimraf _ts4.3 && rimraf coverage",
|
||||
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
|
||||
"lint": "npx nx lint",
|
||||
"test": "jest --coverage --runInBand --verbose",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.14.0",
|
||||
"@typescript-eslint/visitor-keys": "8.14.0",
|
||||
"debug": "^4.3.4",
|
||||
"fast-glob": "^3.3.2",
|
||||
"is-glob": "^4.0.3",
|
||||
"minimatch": "^9.0.4",
|
||||
"semver": "^7.6.0",
|
||||
"ts-api-utils": "^1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jest/types": "29.6.3",
|
||||
"glob": "*",
|
||||
"jest": "29.7.0",
|
||||
"prettier": "^3.2.5",
|
||||
"rimraf": "*",
|
||||
"tmp": "*",
|
||||
"typescript": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"typesVersions": {
|
||||
"<4.7": {
|
||||
"*": [
|
||||
"_ts4.3/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
+265
@@ -0,0 +1,265 @@
|
||||
import type { Parser as ParserType } from './Parser';
|
||||
import type * as ParserOptionsTypes from './ParserOptions';
|
||||
import type { Processor as ProcessorType } from './Processor';
|
||||
import type { LooseRuleDefinition, SharedConfigurationSettings } from './Rule';
|
||||
/** @internal */
|
||||
export declare namespace SharedConfig {
|
||||
type Severity = 0 | 1 | 2;
|
||||
type SeverityString = 'error' | 'off' | 'warn';
|
||||
type RuleLevel = Severity | SeverityString;
|
||||
type RuleLevelAndOptions = [RuleLevel, ...unknown[]];
|
||||
type RuleEntry = RuleLevel | RuleLevelAndOptions;
|
||||
type RulesRecord = Partial<Record<string, RuleEntry>>;
|
||||
type GlobalVariableOptionBase = 'off' | /** @deprecated use `'readonly'` */ 'readable' | 'readonly' | 'writable' | /** @deprecated use `'writable'` */ 'writeable';
|
||||
type GlobalVariableOptionBoolean = /** @deprecated use `'readonly'` */ false | /** @deprecated use `'writable'` */ true;
|
||||
type GlobalVariableOption = GlobalVariableOptionBase | GlobalVariableOptionBoolean;
|
||||
interface GlobalsConfig {
|
||||
[name: string]: GlobalVariableOption;
|
||||
}
|
||||
interface EnvironmentConfig {
|
||||
[name: string]: boolean;
|
||||
}
|
||||
type ParserOptions = ParserOptionsTypes.ParserOptions;
|
||||
interface PluginMeta {
|
||||
/**
|
||||
* The meta.name property should match the npm package name for your plugin.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* The meta.version property should match the npm package version for your plugin.
|
||||
*/
|
||||
version: string;
|
||||
}
|
||||
}
|
||||
export declare namespace ClassicConfig {
|
||||
export type EnvironmentConfig = SharedConfig.EnvironmentConfig;
|
||||
export type GlobalsConfig = SharedConfig.GlobalsConfig;
|
||||
export type GlobalVariableOption = SharedConfig.GlobalVariableOption;
|
||||
export type GlobalVariableOptionBase = SharedConfig.GlobalVariableOptionBase;
|
||||
export type ParserOptions = SharedConfig.ParserOptions;
|
||||
export type RuleEntry = SharedConfig.RuleEntry;
|
||||
export type RuleLevel = SharedConfig.RuleLevel;
|
||||
export type RuleLevelAndOptions = SharedConfig.RuleLevelAndOptions;
|
||||
export type RulesRecord = SharedConfig.RulesRecord;
|
||||
export type Severity = SharedConfig.Severity;
|
||||
export type SeverityString = SharedConfig.SeverityString;
|
||||
interface BaseConfig {
|
||||
$schema?: string;
|
||||
/**
|
||||
* The environment settings.
|
||||
*/
|
||||
env?: EnvironmentConfig;
|
||||
/**
|
||||
* The path to other config files or the package name of shareable configs.
|
||||
*/
|
||||
extends?: string | string[];
|
||||
/**
|
||||
* The global variable settings.
|
||||
*/
|
||||
globals?: GlobalsConfig;
|
||||
/**
|
||||
* The flag that disables directive comments.
|
||||
*/
|
||||
noInlineConfig?: boolean;
|
||||
/**
|
||||
* The override settings per kind of files.
|
||||
*/
|
||||
overrides?: ConfigOverride[];
|
||||
/**
|
||||
* The path to a parser or the package name of a parser.
|
||||
*/
|
||||
parser?: string | null;
|
||||
/**
|
||||
* The parser options.
|
||||
*/
|
||||
parserOptions?: ParserOptions;
|
||||
/**
|
||||
* The plugin specifiers.
|
||||
*/
|
||||
plugins?: string[];
|
||||
/**
|
||||
* The processor specifier.
|
||||
*/
|
||||
processor?: string;
|
||||
/**
|
||||
* The flag to report unused `eslint-disable` comments.
|
||||
*/
|
||||
reportUnusedDisableDirectives?: boolean;
|
||||
/**
|
||||
* The rule settings.
|
||||
*/
|
||||
rules?: RulesRecord;
|
||||
/**
|
||||
* The shared settings.
|
||||
*/
|
||||
settings?: SharedConfigurationSettings;
|
||||
}
|
||||
export interface ConfigOverride extends BaseConfig {
|
||||
excludedFiles?: string | string[];
|
||||
files: string | string[];
|
||||
}
|
||||
export interface Config extends BaseConfig {
|
||||
/**
|
||||
* The glob patterns that ignore to lint.
|
||||
*/
|
||||
ignorePatterns?: string | string[];
|
||||
/**
|
||||
* The root flag.
|
||||
*/
|
||||
root?: boolean;
|
||||
}
|
||||
export {};
|
||||
}
|
||||
export declare namespace FlatConfig {
|
||||
type EcmaVersion = ParserOptionsTypes.EcmaVersion;
|
||||
type GlobalsConfig = SharedConfig.GlobalsConfig;
|
||||
type Parser = ParserType.LooseParserModule;
|
||||
type ParserOptions = SharedConfig.ParserOptions;
|
||||
type PluginMeta = SharedConfig.PluginMeta;
|
||||
type Processor = ProcessorType.LooseProcessorModule;
|
||||
type RuleEntry = SharedConfig.RuleEntry;
|
||||
type RuleLevel = SharedConfig.RuleLevel;
|
||||
type RuleLevelAndOptions = SharedConfig.RuleLevelAndOptions;
|
||||
type Rules = SharedConfig.RulesRecord;
|
||||
type Settings = SharedConfigurationSettings;
|
||||
type Severity = SharedConfig.Severity;
|
||||
type SeverityString = SharedConfig.SeverityString;
|
||||
type SourceType = 'commonjs' | ParserOptionsTypes.SourceType;
|
||||
interface SharedConfigs {
|
||||
[key: string]: Config | ConfigArray;
|
||||
}
|
||||
interface Plugin {
|
||||
/**
|
||||
* Shared configurations bundled with the plugin.
|
||||
* Users will reference these directly in their config (i.e. `plugin.configs.recommended`).
|
||||
*/
|
||||
configs?: SharedConfigs;
|
||||
/**
|
||||
* Metadata about your plugin for easier debugging and more effective caching of plugins.
|
||||
*/
|
||||
meta?: {
|
||||
[K in keyof PluginMeta]?: PluginMeta[K] | undefined;
|
||||
};
|
||||
/**
|
||||
* The definition of plugin processors.
|
||||
* Users can stringly reference the processor using the key in their config (i.e., `"pluginName/processorName"`).
|
||||
*/
|
||||
processors?: Partial<Record<string, Processor>> | undefined;
|
||||
/**
|
||||
* The definition of plugin rules.
|
||||
* The key must be the name of the rule that users will use
|
||||
* Users can stringly reference the rule using the key they registered the plugin under combined with the rule name.
|
||||
* i.e. for the user config `plugins: { foo: pluginReference }` - the reference would be `"foo/ruleName"`.
|
||||
*/
|
||||
rules?: Record<string, LooseRuleDefinition> | undefined;
|
||||
}
|
||||
interface Plugins {
|
||||
/**
|
||||
* We intentionally omit the `configs` key from this object because it avoids
|
||||
* type conflicts with old plugins that haven't updated their configs to flat configs yet.
|
||||
* It's valid to reference these old plugins because ESLint won't access the
|
||||
* `.config` property of a plugin when evaluating a flat config.
|
||||
*/
|
||||
[pluginAlias: string]: Omit<Plugin, 'configs'>;
|
||||
}
|
||||
interface LinterOptions {
|
||||
/**
|
||||
* A Boolean value indicating if inline configuration is allowed.
|
||||
*/
|
||||
noInlineConfig?: boolean;
|
||||
/**
|
||||
* A severity string indicating if and how unused disable and enable
|
||||
* directives should be tracked and reported. For legacy compatibility, `true`
|
||||
* is equivalent to `"warn"` and `false` is equivalent to `"off"`.
|
||||
* @default "off"
|
||||
*/
|
||||
reportUnusedDisableDirectives?: boolean | SharedConfig.Severity | SharedConfig.SeverityString;
|
||||
}
|
||||
interface LanguageOptions {
|
||||
/**
|
||||
* The version of ECMAScript to support.
|
||||
* May be any year (i.e., `2022`) or version (i.e., `5`).
|
||||
* Set to `"latest"` for the most recent supported version.
|
||||
* @default "latest"
|
||||
*/
|
||||
ecmaVersion?: EcmaVersion | undefined;
|
||||
/**
|
||||
* An object specifying additional objects that should be added to the global scope during linting.
|
||||
*/
|
||||
globals?: GlobalsConfig | undefined;
|
||||
/**
|
||||
* An object containing a `parse()` method or a `parseForESLint()` method.
|
||||
* @default
|
||||
* ```
|
||||
* // https://github.com/eslint/espree
|
||||
* require('espree')
|
||||
* ```
|
||||
*/
|
||||
parser?: Parser | undefined;
|
||||
/**
|
||||
* An object specifying additional options that are passed directly to the parser.
|
||||
* The available options are parser-dependent.
|
||||
*/
|
||||
parserOptions?: ParserOptions | undefined;
|
||||
/**
|
||||
* The type of JavaScript source code.
|
||||
* Possible values are `"script"` for traditional script files, `"module"` for ECMAScript modules (ESM), and `"commonjs"` for CommonJS files.
|
||||
* @default
|
||||
* ```
|
||||
* // for `.js` and `.mjs` files
|
||||
* "module"
|
||||
* // for `.cjs` files
|
||||
* "commonjs"
|
||||
* ```
|
||||
*/
|
||||
sourceType?: SourceType | undefined;
|
||||
}
|
||||
interface Config {
|
||||
/**
|
||||
* An array of glob patterns indicating the files that the configuration object should apply to.
|
||||
* If not specified, the configuration object applies to all files matched by any other configuration object.
|
||||
*/
|
||||
files?: (string | string[])[];
|
||||
/**
|
||||
* An array of glob patterns indicating the files that the configuration object should not apply to.
|
||||
* If not specified, the configuration object applies to all files matched by files.
|
||||
*/
|
||||
ignores?: string[];
|
||||
/**
|
||||
* An object containing settings related to how JavaScript is configured for linting.
|
||||
*/
|
||||
languageOptions?: LanguageOptions;
|
||||
/**
|
||||
* An object containing settings related to the linting process.
|
||||
*/
|
||||
linterOptions?: LinterOptions;
|
||||
/**
|
||||
* An string to identify the configuration object. Used in error messages and inspection tools.
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* An object containing a name-value mapping of plugin names to plugin objects.
|
||||
* When `files` is specified, these plugins are only available to the matching files.
|
||||
*/
|
||||
plugins?: Plugins;
|
||||
/**
|
||||
* Either an object containing `preprocess()` and `postprocess()` methods or
|
||||
* a string indicating the name of a processor inside of a plugin
|
||||
* (i.e., `"pluginName/processorName"`).
|
||||
*/
|
||||
processor?: string | Processor;
|
||||
/**
|
||||
* An object containing the configured rules.
|
||||
* When `files` or `ignores` are specified, these rule configurations are only available to the matching files.
|
||||
*/
|
||||
rules?: Rules;
|
||||
/**
|
||||
* An object containing name-value pairs of information that should be available to all rules.
|
||||
*/
|
||||
settings?: Settings;
|
||||
}
|
||||
type ConfigArray = Config[];
|
||||
type ConfigPromise = Promise<ConfigArray>;
|
||||
type ConfigFile = ConfigArray | ConfigPromise;
|
||||
}
|
||||
//# sourceMappingURL=Config.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../src/ts-eslint/Config.ts"],"names":[],"mappings":"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"}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
{
|
||||
"name": "@typescript-eslint/utils",
|
||||
"version": "8.14.0",
|
||||
"description": "Utilities for working with TypeScript + ESLint together",
|
||||
"files": [
|
||||
"dist",
|
||||
"_ts4.3",
|
||||
"package.json",
|
||||
"README.md",
|
||||
"LICENSE"
|
||||
],
|
||||
"type": "commonjs",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
},
|
||||
"./ast-utils": {
|
||||
"types": "./dist/ast-utils/index.d.ts",
|
||||
"default": "./dist/ast-utils/index.js"
|
||||
},
|
||||
"./eslint-utils": {
|
||||
"types": "./dist/eslint-utils/index.d.ts",
|
||||
"default": "./dist/eslint-utils/index.js"
|
||||
},
|
||||
"./json-schema": {
|
||||
"types": "./dist/json-schema.d.ts",
|
||||
"default": "./dist/json-schema.js"
|
||||
},
|
||||
"./ts-eslint": {
|
||||
"types": "./dist/ts-eslint/index.d.ts",
|
||||
"default": "./dist/ts-eslint/index.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"types": "./dist/index.d.ts",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
|
||||
"directory": "packages/utils"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
|
||||
},
|
||||
"homepage": "https://typescript-eslint.io/packages/utils",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"eslint",
|
||||
"typescript",
|
||||
"estree"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc -b tsconfig.build.json",
|
||||
"postbuild": "downlevel-dts dist _ts4.3/dist --to=4.3",
|
||||
"clean": "tsc -b tsconfig.build.json --clean",
|
||||
"postclean": "rimraf dist && rimraf _ts3.4 && rimraf _ts4.3 && rimraf coverage",
|
||||
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
|
||||
"lint": "npx nx lint",
|
||||
"test": "jest --coverage",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.4.0",
|
||||
"@typescript-eslint/scope-manager": "8.14.0",
|
||||
"@typescript-eslint/types": "8.14.0",
|
||||
"@typescript-eslint/typescript-estree": "8.14.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^8.57.0 || ^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"downlevel-dts": "*",
|
||||
"jest": "29.7.0",
|
||||
"prettier": "^3.2.5",
|
||||
"rimraf": "*",
|
||||
"typescript": "*"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"typesVersions": {
|
||||
"<4.7": {
|
||||
"*": [
|
||||
"_ts4.3/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.visitorKeys = void 0;
|
||||
const eslintVisitorKeys = __importStar(require("eslint-visitor-keys"));
|
||||
/*
|
||||
********************************** IMPORTANT NOTE ********************************
|
||||
* *
|
||||
* The key arrays should be sorted in the order in which you would want to visit *
|
||||
* the child keys. *
|
||||
* *
|
||||
* DO NOT SORT THEM ALPHABETICALLY! *
|
||||
* *
|
||||
* They should be sorted in the order that they appear in the source code. *
|
||||
* For example: *
|
||||
* *
|
||||
* class Foo extends Bar { prop: 1 } *
|
||||
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ClassDeclaration *
|
||||
* ^^^ id ^^^ superClass *
|
||||
* ^^^^^^^^^^^ body *
|
||||
* *
|
||||
* It would be incorrect to provide the visitor keys ['body', 'id', 'superClass'] *
|
||||
* because the body comes AFTER everything else in the source code. *
|
||||
* Instead the correct ordering would be ['id', 'superClass', 'body']. *
|
||||
* *
|
||||
**********************************************************************************
|
||||
*/
|
||||
const SharedVisitorKeys = (() => {
|
||||
const FunctionType = ['typeParameters', 'params', 'returnType'];
|
||||
const AnonymousFunction = [...FunctionType, 'body'];
|
||||
const AbstractPropertyDefinition = [
|
||||
'decorators',
|
||||
'key',
|
||||
'typeAnnotation',
|
||||
];
|
||||
return {
|
||||
AbstractPropertyDefinition: ['decorators', 'key', 'typeAnnotation'],
|
||||
AnonymousFunction,
|
||||
AsExpression: ['expression', 'typeAnnotation'],
|
||||
ClassDeclaration: [
|
||||
'decorators',
|
||||
'id',
|
||||
'typeParameters',
|
||||
'superClass',
|
||||
'superTypeArguments',
|
||||
'implements',
|
||||
'body',
|
||||
],
|
||||
Function: ['id', ...AnonymousFunction],
|
||||
FunctionType,
|
||||
PropertyDefinition: [...AbstractPropertyDefinition, 'value'],
|
||||
};
|
||||
})();
|
||||
const additionalKeys = {
|
||||
AccessorProperty: SharedVisitorKeys.PropertyDefinition,
|
||||
ArrayPattern: ['decorators', 'elements', 'typeAnnotation'],
|
||||
ArrowFunctionExpression: SharedVisitorKeys.AnonymousFunction,
|
||||
AssignmentPattern: ['decorators', 'left', 'right', 'typeAnnotation'],
|
||||
CallExpression: ['callee', 'typeArguments', 'arguments'],
|
||||
ClassDeclaration: SharedVisitorKeys.ClassDeclaration,
|
||||
ClassExpression: SharedVisitorKeys.ClassDeclaration,
|
||||
Decorator: ['expression'],
|
||||
ExportAllDeclaration: ['exported', 'source', 'assertions'],
|
||||
ExportNamedDeclaration: ['declaration', 'specifiers', 'source', 'assertions'],
|
||||
FunctionDeclaration: SharedVisitorKeys.Function,
|
||||
FunctionExpression: SharedVisitorKeys.Function,
|
||||
Identifier: ['decorators', 'typeAnnotation'],
|
||||
ImportAttribute: ['key', 'value'],
|
||||
ImportDeclaration: ['specifiers', 'source', 'assertions'],
|
||||
ImportExpression: ['source', 'options'],
|
||||
JSXClosingFragment: [],
|
||||
JSXOpeningElement: ['name', 'typeArguments', 'attributes'],
|
||||
JSXOpeningFragment: [],
|
||||
JSXSpreadChild: ['expression'],
|
||||
MethodDefinition: ['decorators', 'key', 'value'],
|
||||
NewExpression: ['callee', 'typeArguments', 'arguments'],
|
||||
ObjectPattern: ['decorators', 'properties', 'typeAnnotation'],
|
||||
PropertyDefinition: SharedVisitorKeys.PropertyDefinition,
|
||||
RestElement: ['decorators', 'argument', 'typeAnnotation'],
|
||||
StaticBlock: ['body'],
|
||||
TaggedTemplateExpression: ['tag', 'typeArguments', 'quasi'],
|
||||
TSAbstractAccessorProperty: SharedVisitorKeys.AbstractPropertyDefinition,
|
||||
TSAbstractKeyword: [],
|
||||
TSAbstractMethodDefinition: ['key', 'value'],
|
||||
TSAbstractPropertyDefinition: SharedVisitorKeys.AbstractPropertyDefinition,
|
||||
TSAnyKeyword: [],
|
||||
TSArrayType: ['elementType'],
|
||||
TSAsExpression: SharedVisitorKeys.AsExpression,
|
||||
TSAsyncKeyword: [],
|
||||
TSBigIntKeyword: [],
|
||||
TSBooleanKeyword: [],
|
||||
TSCallSignatureDeclaration: SharedVisitorKeys.FunctionType,
|
||||
TSClassImplements: ['expression', 'typeArguments'],
|
||||
TSConditionalType: ['checkType', 'extendsType', 'trueType', 'falseType'],
|
||||
TSConstructorType: SharedVisitorKeys.FunctionType,
|
||||
TSConstructSignatureDeclaration: SharedVisitorKeys.FunctionType,
|
||||
TSDeclareFunction: SharedVisitorKeys.Function,
|
||||
TSDeclareKeyword: [],
|
||||
TSEmptyBodyFunctionExpression: ['id', ...SharedVisitorKeys.FunctionType],
|
||||
TSEnumBody: ['members'],
|
||||
TSEnumDeclaration: ['id', 'body'],
|
||||
TSEnumMember: ['id', 'initializer'],
|
||||
TSExportAssignment: ['expression'],
|
||||
TSExportKeyword: [],
|
||||
TSExternalModuleReference: ['expression'],
|
||||
TSFunctionType: SharedVisitorKeys.FunctionType,
|
||||
TSImportEqualsDeclaration: ['id', 'moduleReference'],
|
||||
TSImportType: ['argument', 'qualifier', 'typeArguments'],
|
||||
TSIndexedAccessType: ['indexType', 'objectType'],
|
||||
TSIndexSignature: ['parameters', 'typeAnnotation'],
|
||||
TSInferType: ['typeParameter'],
|
||||
TSInstantiationExpression: ['expression', 'typeArguments'],
|
||||
TSInterfaceBody: ['body'],
|
||||
TSInterfaceDeclaration: ['id', 'typeParameters', 'extends', 'body'],
|
||||
TSInterfaceHeritage: ['expression', 'typeArguments'],
|
||||
TSIntersectionType: ['types'],
|
||||
TSIntrinsicKeyword: [],
|
||||
TSLiteralType: ['literal'],
|
||||
TSMappedType: ['key', 'constraint', 'nameType', 'typeAnnotation'],
|
||||
TSMethodSignature: ['typeParameters', 'key', 'params', 'returnType'],
|
||||
TSModuleBlock: ['body'],
|
||||
TSModuleDeclaration: ['id', 'body'],
|
||||
TSNamedTupleMember: ['label', 'elementType'],
|
||||
TSNamespaceExportDeclaration: ['id'],
|
||||
TSNeverKeyword: [],
|
||||
TSNonNullExpression: ['expression'],
|
||||
TSNullKeyword: [],
|
||||
TSNumberKeyword: [],
|
||||
TSObjectKeyword: [],
|
||||
TSOptionalType: ['typeAnnotation'],
|
||||
TSParameterProperty: ['decorators', 'parameter'],
|
||||
TSPrivateKeyword: [],
|
||||
TSPropertySignature: ['typeAnnotation', 'key'],
|
||||
TSProtectedKeyword: [],
|
||||
TSPublicKeyword: [],
|
||||
TSQualifiedName: ['left', 'right'],
|
||||
TSReadonlyKeyword: [],
|
||||
TSRestType: ['typeAnnotation'],
|
||||
TSSatisfiesExpression: SharedVisitorKeys.AsExpression,
|
||||
TSStaticKeyword: [],
|
||||
TSStringKeyword: [],
|
||||
TSSymbolKeyword: [],
|
||||
TSTemplateLiteralType: ['quasis', 'types'],
|
||||
TSThisType: [],
|
||||
TSTupleType: ['elementTypes'],
|
||||
TSTypeAliasDeclaration: ['id', 'typeParameters', 'typeAnnotation'],
|
||||
TSTypeAnnotation: ['typeAnnotation'],
|
||||
TSTypeAssertion: ['typeAnnotation', 'expression'],
|
||||
TSTypeLiteral: ['members'],
|
||||
TSTypeOperator: ['typeAnnotation'],
|
||||
TSTypeParameter: ['name', 'constraint', 'default'],
|
||||
TSTypeParameterDeclaration: ['params'],
|
||||
TSTypeParameterInstantiation: ['params'],
|
||||
TSTypePredicate: ['typeAnnotation', 'parameterName'],
|
||||
TSTypeQuery: ['exprName', 'typeArguments'],
|
||||
TSTypeReference: ['typeName', 'typeArguments'],
|
||||
TSUndefinedKeyword: [],
|
||||
TSUnionType: ['types'],
|
||||
TSUnknownKeyword: [],
|
||||
TSVoidKeyword: [],
|
||||
};
|
||||
const visitorKeys = eslintVisitorKeys.unionWith(additionalKeys);
|
||||
exports.visitorKeys = visitorKeys;
|
||||
//# sourceMappingURL=visitor-keys.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"visitor-keys.js","sourceRoot":"","sources":["../src/visitor-keys.ts"],"names":[],"mappings":"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"}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"name": "@typescript-eslint/visitor-keys",
|
||||
"version": "8.14.0",
|
||||
"description": "Visitor keys used to help traverse the TypeScript-ESTree AST",
|
||||
"files": [
|
||||
"dist",
|
||||
"_ts4.3",
|
||||
"package.json",
|
||||
"README.md",
|
||||
"LICENSE"
|
||||
],
|
||||
"type": "commonjs",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"types": "./dist/index.d.ts",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/typescript-eslint/typescript-eslint.git",
|
||||
"directory": "packages/visitor-keys"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/typescript-eslint/typescript-eslint/issues"
|
||||
},
|
||||
"homepage": "https://typescript-eslint.io",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"eslint",
|
||||
"typescript",
|
||||
"estree"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc -b tsconfig.build.json",
|
||||
"postbuild": "downlevel-dts dist _ts4.3/dist --to=4.3",
|
||||
"clean": "tsc -b tsconfig.build.json --clean",
|
||||
"postclean": "rimraf dist && rimraf _ts3.4 && rimraf _ts4.3 && rimraf coverage",
|
||||
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
|
||||
"lint": "npx nx lint",
|
||||
"test": "jest --coverage",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.14.0",
|
||||
"eslint-visitor-keys": "^3.4.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jest/types": "29.6.3",
|
||||
"@types/eslint-visitor-keys": "*",
|
||||
"downlevel-dts": "*",
|
||||
"jest": "29.7.0",
|
||||
"prettier": "^3.2.5",
|
||||
"rimraf": "*",
|
||||
"typescript": "*"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"typesVersions": {
|
||||
"<4.7": {
|
||||
"*": [
|
||||
"_ts4.3/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user