@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 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
- const symbol = typeChecker.getSymbolAtLocation(node);
20567
- return symbol?.flags && (symbol.flags & ts$1.SymbolFlags.Alias) !== 0 ? typeChecker.getAliasedSymbol(symbol) : symbol;
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 || ts$1.isTypeParameterDeclaration(parent)) return true;
20633
- if (ts$1.isTypeNode(parent) && !ts$1.isExpressionWithTypeArguments(parent)) return true;
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.0",
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/build": "^0.1.0",
39
- "@flint.fyi/rule-tester": "^0.18.0"
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"