@flint.fyi/ts 0.23.0 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +0 -14
- package/dist/index.mjs +8 -90
- package/package.json +5 -5
package/dist/index.d.mts
CHANGED
|
@@ -958,13 +958,6 @@ declare const ts: import("@flint.fyi/core").Plugin<import("@flint.fyi/core").Rul
|
|
|
958
958
|
readonly pluginId: string;
|
|
959
959
|
readonly url: string;
|
|
960
960
|
}, "implicitExports", undefined>, import("@flint.fyi/core").Rule<{
|
|
961
|
-
readonly description: "Reports using `module` keyword instead of `namespace` for TypeScript namespaces.";
|
|
962
|
-
readonly id: "namespaceKeywords";
|
|
963
|
-
readonly presets: readonly ["stylistic", "stylisticStrict"];
|
|
964
|
-
} & {
|
|
965
|
-
readonly pluginId: string;
|
|
966
|
-
readonly url: string;
|
|
967
|
-
}, "preferNamespace", undefined>, import("@flint.fyi/core").Rule<{
|
|
968
961
|
readonly description: "Reports extending the prototype of native JavaScript objects.";
|
|
969
962
|
readonly id: "nativeObjectExtensions";
|
|
970
963
|
readonly presets: readonly ["javascript"];
|
|
@@ -1203,13 +1196,6 @@ declare const ts: import("@flint.fyi/core").Plugin<import("@flint.fyi/core").Rul
|
|
|
1203
1196
|
readonly pluginId: string;
|
|
1204
1197
|
readonly url: string;
|
|
1205
1198
|
}, "noOctalEscape", undefined>, import("@flint.fyi/core").Rule<{
|
|
1206
|
-
readonly description: "Reports using legacy octal numeric literals.";
|
|
1207
|
-
readonly id: "octalNumbers";
|
|
1208
|
-
readonly presets: readonly ["javascript"];
|
|
1209
|
-
} & {
|
|
1210
|
-
readonly pluginId: string;
|
|
1211
|
-
readonly url: string;
|
|
1212
|
-
}, "noOctalNumber", undefined>, import("@flint.fyi/core").Rule<{
|
|
1213
1199
|
readonly description: "Prefer assignment operator shorthand where possible.";
|
|
1214
1200
|
readonly id: "operatorAssignmentShorthand";
|
|
1215
1201
|
readonly presets: readonly ["stylistic", "stylisticStrict"];
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RuleCreator, createPlugin } from "@flint.fyi/core";
|
|
2
2
|
import { declarationIncludesGlobal, forEachChild, getModifyingReferences, getScopeManager, getStaticNumberValue, getStaticStringValue, getStaticValue, getTSNodeRange, hasSameTokens, isBuiltinArrayMethod, isFunction, isGlobalDeclaration, isGlobalDeclarationOfName, isGlobalVariable, isInlineArrayCreation, typescriptLanguage, unwrapParentParenthesizedExpressions, unwrapParenthesizedNode } from "@flint.fyi/typescript-language";
|
|
3
|
-
import ts$1, { NodeFlags, SignatureKind, SymbolFlags, SyntaxKind, TypeFlags, getLeadingCommentRanges, getTrailingCommentRanges, isArrayLiteralExpression, isBigIntLiteral, isElementAccessExpression, isFunctionLike, isIdentifier, isInterfaceDeclaration, isLiteralExpression, isNewExpression, isNumericLiteral, isParenthesizedExpression, isPrefixUnaryExpression, isPropertyAccessExpression, isSpreadElement, isStringLiteral, isVariableDeclaration } from "typescript";
|
|
3
|
+
import ts$1, { NodeFlags, SignatureKind, SymbolFlags, SyntaxKind, TypeFlags, getLeadingCommentRanges, getTrailingCommentRanges, isArrayLiteralExpression, isBigIntLiteral, isElementAccessExpression, isExpressionWithTypeArguments, isFunctionLike, isIdentifier, isInterfaceDeclaration, isLiteralExpression, isNewExpression, isNumericLiteral, isParenthesizedExpression, isPrefixUnaryExpression, isPropertyAccessExpression, isShorthandPropertyAssignment, isSpreadElement, isStringLiteral, isTypeNode, isTypeParameterDeclaration, isVariableDeclaration } from "typescript";
|
|
4
4
|
import * as tsutils from "ts-api-utils";
|
|
5
5
|
import { isNodeFlagSet, isNullKeyword } from "ts-api-utils";
|
|
6
6
|
import { nullThrows, pathKey } from "@flint.fyi/utils";
|
|
@@ -7744,40 +7744,6 @@ var namespaceImplicitAmbientImports_default = ruleCreator.createRule(typescriptL
|
|
|
7744
7744
|
}
|
|
7745
7745
|
});
|
|
7746
7746
|
//#endregion
|
|
7747
|
-
//#region src/rules/namespaceKeywords.ts
|
|
7748
|
-
var namespaceKeywords_default = ruleCreator.createRule(typescriptLanguage, {
|
|
7749
|
-
about: {
|
|
7750
|
-
description: "Reports using `module` keyword instead of `namespace` for TypeScript namespaces.",
|
|
7751
|
-
id: "namespaceKeywords",
|
|
7752
|
-
presets: ["stylistic", "stylisticStrict"]
|
|
7753
|
-
},
|
|
7754
|
-
messages: { preferNamespace: {
|
|
7755
|
-
primary: "The `namespace` keyword is preferred over `module` for TypeScript namespaces.",
|
|
7756
|
-
secondary: [
|
|
7757
|
-
"TypeScript originally used the `module` keyword to declare internal modules (namespaces).",
|
|
7758
|
-
"The `namespace` keyword was later introduced to avoid confusion with ES6 modules.",
|
|
7759
|
-
"Using `namespace` makes it clear you are defining a TypeScript namespace, not an ES6 module."
|
|
7760
|
-
],
|
|
7761
|
-
suggestions: ["Replace `module` with `namespace`."]
|
|
7762
|
-
} },
|
|
7763
|
-
setup(context) {
|
|
7764
|
-
return { visitors: { ModuleDeclaration: (node, { sourceFile }) => {
|
|
7765
|
-
if (node.name.kind === SyntaxKind.StringLiteral) return;
|
|
7766
|
-
const moduleKeywordToken = node.getChildren(sourceFile).find((child) => child.kind === SyntaxKind.ModuleKeyword);
|
|
7767
|
-
if (!moduleKeywordToken) return;
|
|
7768
|
-
const range = getTSNodeRange(moduleKeywordToken, sourceFile);
|
|
7769
|
-
context.report({
|
|
7770
|
-
fix: {
|
|
7771
|
-
range,
|
|
7772
|
-
text: "namespace"
|
|
7773
|
-
},
|
|
7774
|
-
message: "preferNamespace",
|
|
7775
|
-
range
|
|
7776
|
-
});
|
|
7777
|
-
} } };
|
|
7778
|
-
}
|
|
7779
|
-
});
|
|
7780
|
-
//#endregion
|
|
7781
7747
|
//#region src/rules/nativeObjectExtensions.ts
|
|
7782
7748
|
const nativeConstructors = /* @__PURE__ */ new Set([
|
|
7783
7749
|
"AggregateError",
|
|
@@ -10083,55 +10049,6 @@ var octalEscapes_default = ruleCreator.createRule(typescriptLanguage, {
|
|
|
10083
10049
|
}
|
|
10084
10050
|
});
|
|
10085
10051
|
//#endregion
|
|
10086
|
-
//#region src/rules/octalNumbers.ts
|
|
10087
|
-
var octalNumbers_default = ruleCreator.createRule(typescriptLanguage, {
|
|
10088
|
-
about: {
|
|
10089
|
-
description: "Reports using legacy octal numeric literals.",
|
|
10090
|
-
id: "octalNumbers",
|
|
10091
|
-
presets: ["javascript"]
|
|
10092
|
-
},
|
|
10093
|
-
messages: { noOctalNumber: {
|
|
10094
|
-
primary: "This legacy octal numeric literal evaluates to {{ raw }}. Did you mean that value, or to use a modern octal syntax such as {{ equivalent }}?",
|
|
10095
|
-
secondary: [
|
|
10096
|
-
"Legacy octal numeric literals (e.g., `077`, `0123`) are a deprecated feature in JavaScript that can lead to confusion and errors.",
|
|
10097
|
-
"They are forbidden in strict mode and are less readable than their modern alternatives.",
|
|
10098
|
-
"The digit `0` by itself is allowed as it represents zero, not an octal literal."
|
|
10099
|
-
],
|
|
10100
|
-
suggestions: ["Use the explicit octal syntax (e.g., `0o77`) introduced in ES6, which is clearer and works in both strict and non-strict modes.", "Remove the leading `0` if you intended to use the decimal value."]
|
|
10101
|
-
} },
|
|
10102
|
-
setup(context) {
|
|
10103
|
-
return { visitors: { NumericLiteral: (node, { sourceFile }) => {
|
|
10104
|
-
const text = node.getText(sourceFile);
|
|
10105
|
-
if (text.length > 1 && text.startsWith("0") && nullThrows(text[1], "Second character is expected to be present by prior length check") >= "0" && nullThrows(text[1], "Second character is expected to be present by prior length check") <= "7" && !/^0[xobi]/i.test(text)) {
|
|
10106
|
-
const range = {
|
|
10107
|
-
begin: node.getStart(sourceFile),
|
|
10108
|
-
end: node.getEnd()
|
|
10109
|
-
};
|
|
10110
|
-
const octalValue = parseInt(text, 8);
|
|
10111
|
-
const modernOctalSyntax = `0o${text.slice(1)}`;
|
|
10112
|
-
const decimalWithoutLeadingZero = text.slice(1);
|
|
10113
|
-
context.report({
|
|
10114
|
-
data: {
|
|
10115
|
-
equivalent: modernOctalSyntax,
|
|
10116
|
-
raw: octalValue.toString()
|
|
10117
|
-
},
|
|
10118
|
-
message: "noOctalNumber",
|
|
10119
|
-
range,
|
|
10120
|
-
suggestions: [{
|
|
10121
|
-
id: "useModernOctalSyntax",
|
|
10122
|
-
range,
|
|
10123
|
-
text: modernOctalSyntax
|
|
10124
|
-
}, {
|
|
10125
|
-
id: "removeLeadingZero",
|
|
10126
|
-
range,
|
|
10127
|
-
text: decimalWithoutLeadingZero
|
|
10128
|
-
}]
|
|
10129
|
-
});
|
|
10130
|
-
}
|
|
10131
|
-
} } };
|
|
10132
|
-
}
|
|
10133
|
-
});
|
|
10134
|
-
//#endregion
|
|
10135
10052
|
//#region src/rules/operatorAssignmentShorthand.ts
|
|
10136
10053
|
const operatorTexts = /* @__PURE__ */ new Map([
|
|
10137
10054
|
[SyntaxKind.AmpersandToken, "&"],
|
|
@@ -20563,8 +20480,11 @@ function getImportSpecifiers(node) {
|
|
|
20563
20480
|
return specifiers;
|
|
20564
20481
|
}
|
|
20565
20482
|
function getReferencedSymbol(typeChecker, node) {
|
|
20566
|
-
|
|
20567
|
-
|
|
20483
|
+
let symbol;
|
|
20484
|
+
const parent = node.parent;
|
|
20485
|
+
if (isShorthandPropertyAssignment(parent)) symbol = typeChecker.getShorthandAssignmentValueSymbol(parent);
|
|
20486
|
+
else symbol = typeChecker.getSymbolAtLocation(node);
|
|
20487
|
+
return symbol?.flags && (symbol.flags & SymbolFlags.Alias) !== 0 ? typeChecker.getAliasedSymbol(symbol) : symbol;
|
|
20568
20488
|
}
|
|
20569
20489
|
function getSpecifierLocal(specifier) {
|
|
20570
20490
|
return specifier.kind === SyntaxKind.Identifier ? specifier : specifier.name;
|
|
@@ -20629,8 +20549,8 @@ function isOnlyTypeReference(node) {
|
|
|
20629
20549
|
let parent = node.parent;
|
|
20630
20550
|
while (parent) {
|
|
20631
20551
|
if (parent.kind === SyntaxKind.HeritageClause) return parent.token === SyntaxKind.ImplementsKeyword;
|
|
20632
|
-
if (parent.kind === SyntaxKind.TypeAliasDeclaration || parent.kind === SyntaxKind.InterfaceDeclaration ||
|
|
20633
|
-
if (
|
|
20552
|
+
if (parent.kind === SyntaxKind.TypeAliasDeclaration || parent.kind === SyntaxKind.InterfaceDeclaration || isTypeParameterDeclaration(parent)) return true;
|
|
20553
|
+
if (isTypeNode(parent) && !isExpressionWithTypeArguments(parent)) return true;
|
|
20634
20554
|
current = parent;
|
|
20635
20555
|
parent = current.parent;
|
|
20636
20556
|
}
|
|
@@ -22292,7 +22212,6 @@ const ts = createPlugin({
|
|
|
22292
22212
|
namedDefaultExports_default,
|
|
22293
22213
|
namespaceDeclarations_default,
|
|
22294
22214
|
namespaceImplicitAmbientImports_default,
|
|
22295
|
-
namespaceKeywords_default,
|
|
22296
22215
|
nativeObjectExtensions_default,
|
|
22297
22216
|
negativeIndexLengthMethods_default,
|
|
22298
22217
|
negativeZeroComparisons_default,
|
|
@@ -22324,7 +22243,6 @@ const ts = createPlugin({
|
|
|
22324
22243
|
objectSpreadUnnecessaryFallbacks_default,
|
|
22325
22244
|
objectTypeDefinitions_default,
|
|
22326
22245
|
octalEscapes_default,
|
|
22327
|
-
octalNumbers_default,
|
|
22328
22246
|
operatorAssignmentShorthand_default,
|
|
22329
22247
|
overloadSignaturesAdjacent_default,
|
|
22330
22248
|
parameterReassignments_default,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flint.fyi/ts",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.1",
|
|
4
4
|
"description": "[Experimental] TypeScript language plugin for Flint.",
|
|
5
5
|
"homepage": "https://flint.fyi/rules/ts",
|
|
6
6
|
"repository": {
|
|
@@ -28,15 +28,15 @@
|
|
|
28
28
|
"ts-api-utils": "^2.4.0",
|
|
29
29
|
"typescript": "^6.0.0",
|
|
30
30
|
"zod": "^4.3.6",
|
|
31
|
-
"@flint.fyi/typescript-language": "^0.20.0",
|
|
32
31
|
"@flint.fyi/core": "^0.25.0",
|
|
33
|
-
"@flint.fyi/utils": "^0.16.0"
|
|
32
|
+
"@flint.fyi/utils": "^0.16.0",
|
|
33
|
+
"@flint.fyi/typescript-language": "^0.20.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"tsdown": "0.22.3",
|
|
37
37
|
"vitest": "4.1.0",
|
|
38
|
-
"@flint.fyi/
|
|
39
|
-
"@flint.fyi/
|
|
38
|
+
"@flint.fyi/rule-tester": "^0.19.0",
|
|
39
|
+
"@flint.fyi/build": "^0.1.0"
|
|
40
40
|
},
|
|
41
41
|
"engines": {
|
|
42
42
|
"node": ">=26.1.0"
|