@konvert7/klint 1.4.0 → 1.4.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/README.md CHANGED
@@ -745,7 +745,7 @@ doc-comments alongside `/** */`.
745
745
  | `no-string-match` | `String#match()` usage better expressed with clearer APIs |
746
746
  | `blank-line-before-control-flow` | Blank line above a control-flow statement that follows another statement; autofix |
747
747
  | `blank-line-after-block` | Blank line below a block statement when another statement follows; autofix |
748
- | `cognitive-complexity` | Function whose cognitive complexity (Biome / SonarSource model) is above `max`, in all five languages; opt-in, no autofix |
748
+ | `cognitive-complexity` | Function whose cognitive complexity (SonarJS / SonarSource model) is above `max`, in all five languages; opt-in, no autofix |
749
749
  | `function-length` | Function whose body has more lines than `max` (counted like Biome's `noExcessiveLinesPerFunction`), in all five languages; opt-in, no autofix |
750
750
 
751
751
  Rules that needed TypeScript's type checker were removed in 1.0; see [Upgrading from klint 0.x](#upgrading-from-klint-0x).
@@ -800,7 +800,7 @@ rules:
800
800
 
801
801
  ### Cognitive complexity
802
802
 
803
- `cognitive-complexity` reports every function whose cognitive complexity is above `max`, in TypeScript/JavaScript, Python, Swift, Rust and C#. It is opt-in and has no fix. It uses Biome 2.6.5's `noExcessiveCognitiveComplexity` scoring (the SonarSource Cognitive Complexity model, G. Ann Campbell 2017) for every language, so a TypeScript function gets the same score as in Biome.
803
+ `cognitive-complexity` reports every function whose cognitive complexity is above `max`, in TypeScript/JavaScript, Python, Swift, Rust and C#. It is opt-in and has no fix. It scores like SonarSource's own implementation, `eslint-plugin-sonarjs` 3.0.5 rule S3776 (the SonarSource Cognitive Complexity model, G. Ann Campbell 2017), for every language, so a TypeScript function gets the same score as in SonarJS.
804
804
 
805
805
  ```yaml
806
806
  rules:
@@ -821,37 +821,38 @@ rules:
821
821
  - The message has the form ``Function `big` has cognitive complexity 16 (max 15) — split it into smaller functions.``. The name is the declared name. For an anonymous function assigned to a variable or property it is that name. Otherwise it is `<anonymous>`. The line is the function's first line.
822
822
  - Each function starts at 0. Top-level code is not scored.
823
823
 
824
- **Scoring.** "Nesting" is how deep a construct sits: each enclosing `if`, loop, `switch`, `catch`, `guard`, `let … else` body and each enclosing function adds one.
824
+ **Scoring.** "Nesting" is how deep a construct sits: nesting is added by each enclosing `if`, loop, `switch`, `catch`, `guard` and `let … else` body; a nested function starts again at 0. Only a construct's body is nested: its condition, loop head, `switch` value or ternary test sits at the construct's own nesting. For example, in `if (a ? b : c) {}` the ternary adds 1, not 2.
825
825
 
826
826
  | Increment | TypeScript / JavaScript | Python | Swift | Rust | C# |
827
827
  |---|---|---|---|---|---|
828
- | +1 plus nesting: `if`, and `else if` (which also gets the nesting) | `if`, `else if` | `if`, `elif` | `if`, `else if` | `if`, `if let`, `else if` | `if`, `else if` |
828
+ | +1 plus nesting: `if` | `if` | `if` | `if`, `if let` | `if` |
829
+ | +1, no nesting: `else if` (its body is nested like the `if` body) | `else if` | `elif` | `else if` | `else if` | `else if` |
829
830
  | +1 plus nesting: ternary | `?:` | `x if c else y` | `?:` | — | `?:` |
830
831
  | +1 plus nesting: switch / match | `switch` | `match` | `switch` | `match` | `switch` statement, `switch` expression |
831
832
  | +1 plus nesting: loops | `for`, `for…in`, `for…of`, `while`, `do…while` | `for`, `while` | `for`, `while`, `repeat…while` | `for`, `while`, `while let`, `loop` | `for`, `foreach`, `while`, `do` |
832
833
  | +1 plus nesting: `catch` | `catch` | `except` | `catch` | — | `catch` |
833
834
  | +1 plus nesting: `guard`, `let … else` (its `else` body is nested) | — | — | `guard` | `let … else` | — |
834
- | +1, no nesting: `finally` (its body is not nested) | `finally` | `finally` | — | — | `finally` |
835
- | nesting only: nested function (scored on its own, see below) | arrow, function expression, function declaration, method | `lambda`, `def` | closure | closure | lambda, local function, anonymous method |
835
+ | no increment: nested function (scored on its own, starting at nesting 0) | arrow, function expression, function declaration, method | `lambda`, `def` | closure | closure | lambda, local function, anonymous method |
836
836
  | +1, no nesting: plain `else` (not `else if`/`elif`) | `else` | `else` of `if`, `try`, `for`, `while` | `else` | `else` | `else` |
837
837
  | +1: labeled `break` / `continue`, `goto` | `break label`, `continue label` | — | `break label`, `continue label` | `break 'label`, `continue 'label` | `goto` |
838
- | +1 per logical operator, unless its direct parent is the same operator | `&&`, `\|\|`, `??` | `and`, `or` | `&&`, `\|\|`, `??` | `&&`, `\|\|` | `&&`, `\|\|`, `??`, pattern `and`, `or` |
838
+ | +1 per run of `&&` (see below); `\|\|`, `or`, `??` add nothing | `&&` | `and` | `&&` | `&&` | `&&`, pattern `and` |
839
839
  | +1: comprehension `if` | — | comprehension `if` | — | — | — |
840
840
  | +1: guard on a case or arm | — | — | `case … where` | match-arm guard | `when` clause |
841
841
 
842
- Each logical operator scores +1, unless its direct parent is a logical operator of the same kind. Parentheses break that link, so a parenthesised group scores on its own: `a && b || c` is 2, `a && (b || c) && a` is 2, `a && (b && c)` is 2, and `a ?? b ?? c` is 1. Negation (`!`, `not`) adds nothing.
842
+ Logical operators form one sequence per expression, read in source order through parentheses; negation, calls and other expressions start a new sequence. Each `&&` (`and`) scores +1 unless the operator before it in the sequence is also `&&`. `||`, `or`, `??` and pattern `or` add nothing but end a run: `a && b || c` is 1, `a && (b || c) && a` is 2, `a && (b && c)` is 1, and `a ?? b ?? c` is 0. Negation (`!`, `not`) adds nothing. In TypeScript/JavaScript, a short-circuit directly inside a JSX expression that uses one operator and has no ternary operand (`{a && <X/>}`, `{a && b && <X/>}`) adds nothing; a mixed one (`{a && b || <X/>}`) is counted as usual. A function used as a branch of a conditional expression (`a ? () => {…} : b` in TypeScript/JavaScript and C#, a Swift closure in a ternary, `(lambda: …) if a else b` in Python) is scored on its own from nesting 0 like any nested function, and every later construct in the enclosing function that adds "plus nesting" in the table above scores one more.
843
843
 
844
- It adds nothing for `try` itself, `return`, `throw`, recursion, Rust `?`, Python `with`, Swift `do` without `catch`, an `if let` or `while let` beyond the `if` or `while`, optional chaining `?.`, assignment operators `||=`, `&&=`, `??=`, and a Rust `let` without `else`.
844
+ It adds nothing for `try` itself, `finally`, `return`, `throw`, recursion, Rust `?`, Python `with`, Swift `do` without `catch`, an `if let` or `while let` beyond the `if` or `while`, optional chaining `?.`, assignment operators `||=`, `&&=`, `??=`, and a Rust `let` without `else`.
845
845
 
846
- **Differences from the Sonar paper.** This rule follows Biome, which differs from the paper in these places:
846
+ **Differences from the Sonar paper.** SonarJS, and so klint, departs from the 2017 paper in one place: `||` (Python `or`, C# pattern `or`) adds nothing; the paper counts it.
847
847
 
848
- - `else if` gets the nesting increment.
849
- - `finally` adds one and does not nest its body.
850
- - `??` counts as a boolean operator.
851
- - A logical operator is scored unless its direct parent is the same operator, so `a && (b && c)` is 2, not 1.
852
- - Recursion adds nothing.
853
- - Biome 2.6.5 lowers the nesting level of the code after a plain `else` (an unbalanced decrement), so it can score such functions lower; klint keeps the nesting.
854
- - A nested function (closure, lambda, arrow, local function) is scored and reported on its own. It starts at its enclosing nesting level plus one and does not add to the outer function.
848
+ **Differences from Biome 2.6.5.** Biome's `noExcessiveCognitiveComplexity` differs from SonarJS in four ways, and klint follows SonarJS:
849
+
850
+ - `else if` gets no nesting increment (Biome adds it).
851
+ - `??` adds nothing (Biome counts it).
852
+ - `||` adds nothing (Biome counts it).
853
+ - Biome 2.6.5 lowers the nesting level of the code after a plain `else` (an unbalanced decrement). That is a Biome bug; klint keeps the nesting.
854
+
855
+ A nested function (closure, lambda, arrow, local function) is scored and reported on its own and does not add to the outer function.
855
856
 
856
857
  **What counts as a function.** TypeScript/JavaScript: `function` declarations and expressions, arrow functions, methods (including getters and setters), generator functions. Python: `def` and `lambda`. Swift: `func`, `init`, `deinit`, closures, computed getters and setters. Rust: `fn` items and closures. C#: methods, constructors, destructors, local functions, lambdas, anonymous methods, property and indexer accessors, operators and conversion operators.
857
858
 
package/klint.schema.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://raw.githubusercontent.com/konvert7/klint/refs/tags/v1.4.0/klint.schema.json",
2
+ "$id": "https://raw.githubusercontent.com/konvert7/klint/refs/tags/v1.4.1/klint.schema.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "additionalProperties": false,
5
5
  "description": "klint configuration. Lives at klint.yaml (or klint.config.json) next to biome.json and knip.json.",
@@ -774,7 +774,7 @@
774
774
  "type": "object"
775
775
  }
776
776
  ],
777
- "description": "Reports every function whose cognitive complexity is above `max` (default 15), scored like Biome 2.6.5's `noExcessiveCognitiveComplexity` (the SonarSource Cognitive Complexity model). Works on TypeScript/JavaScript, Python, Swift, Rust and C#. Opt-in; no autofix.",
777
+ "description": "Reports every function whose cognitive complexity is above `max` (default 15), scored like `eslint-plugin-sonarjs` 3.0.5's `cognitive-complexity` (SonarSource rule S3776). Works on TypeScript/JavaScript, Python, Swift, Rust and C#. Opt-in; no autofix.",
778
778
  "examples": [
779
779
  "cognitive-complexity: error",
780
780
  "cognitive-complexity:\n severity: warn\n include: [\"src/**\", \"!src/generated/**\"]\n max: 14"
@@ -1591,7 +1591,7 @@
1591
1591
  "type": "object"
1592
1592
  }
1593
1593
  ],
1594
- "description": "Reports every function whose cognitive complexity is above `max` (default 15), scored like Biome 2.6.5's `noExcessiveCognitiveComplexity` (the SonarSource Cognitive Complexity model). Works on TypeScript/JavaScript, Python, Swift, Rust and C#. Opt-in; no autofix.",
1594
+ "description": "Reports every function whose cognitive complexity is above `max` (default 15), scored like `eslint-plugin-sonarjs` 3.0.5's `cognitive-complexity` (SonarSource rule S3776). Works on TypeScript/JavaScript, Python, Swift, Rust and C#. Opt-in; no autofix.",
1595
1595
  "examples": [
1596
1596
  "cognitive-complexity: error",
1597
1597
  "cognitive-complexity:\n severity: warn\n include: [\"src/**\", \"!src/generated/**\"]\n max: 14"
package/klint.schema.yaml CHANGED
@@ -1,4 +1,4 @@
1
- $id: https://raw.githubusercontent.com/konvert7/klint/refs/tags/v1.4.0/klint.schema.json
1
+ $id: https://raw.githubusercontent.com/konvert7/klint/refs/tags/v1.4.1/klint.schema.json
2
2
  $schema: http://json-schema.org/draft-07/schema#
3
3
  additionalProperties: false
4
4
  description: klint configuration. Lives at klint.yaml (or klint.config.json) next to biome.json and knip.json.
@@ -588,7 +588,7 @@ properties:
588
588
  - null
589
589
  type: string
590
590
  type: object
591
- description: Reports every function whose cognitive complexity is above `max` (default 15), scored like Biome 2.6.5's `noExcessiveCognitiveComplexity` (the SonarSource Cognitive Complexity model). Works on TypeScript/JavaScript, Python, Swift, Rust and C#. Opt-in; no autofix.
591
+ description: Reports every function whose cognitive complexity is above `max` (default 15), scored like `eslint-plugin-sonarjs` 3.0.5's `cognitive-complexity` (SonarSource rule S3776). Works on TypeScript/JavaScript, Python, Swift, Rust and C#. Opt-in; no autofix.
592
592
  examples:
593
593
  - 'cognitive-complexity: error'
594
594
  - |-
@@ -1176,7 +1176,7 @@ properties:
1176
1176
  - null
1177
1177
  type: string
1178
1178
  type: object
1179
- description: Reports every function whose cognitive complexity is above `max` (default 15), scored like Biome 2.6.5's `noExcessiveCognitiveComplexity` (the SonarSource Cognitive Complexity model). Works on TypeScript/JavaScript, Python, Swift, Rust and C#. Opt-in; no autofix.
1179
+ description: Reports every function whose cognitive complexity is above `max` (default 15), scored like `eslint-plugin-sonarjs` 3.0.5's `cognitive-complexity` (SonarSource rule S3776). Works on TypeScript/JavaScript, Python, Swift, Rust and C#. Opt-in; no autofix.
1180
1180
  examples:
1181
1181
  - 'cognitive-complexity: error'
1182
1182
  - |-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@konvert7/klint",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "Architecture-as-Code linter for TypeScript. Enforce layer boundaries, import rules, and singleton patterns in YAML.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -56,12 +56,12 @@
56
56
  ]
57
57
  },
58
58
  "optionalDependencies": {
59
- "@konvert7/klint-darwin-arm64": "1.4.0",
60
- "@konvert7/klint-darwin-x64": "1.4.0",
61
- "@konvert7/klint-linux-arm64": "1.4.0",
62
- "@konvert7/klint-linux-x64": "1.4.0",
63
- "@konvert7/klint-linux-x64-musl": "1.4.0",
64
- "@konvert7/klint-win32-x64": "1.4.0"
59
+ "@konvert7/klint-darwin-arm64": "1.4.1",
60
+ "@konvert7/klint-darwin-x64": "1.4.1",
61
+ "@konvert7/klint-linux-arm64": "1.4.1",
62
+ "@konvert7/klint-linux-x64": "1.4.1",
63
+ "@konvert7/klint-linux-x64-musl": "1.4.1",
64
+ "@konvert7/klint-win32-x64": "1.4.1"
65
65
  },
66
66
  "devDependencies": {
67
67
  "@biomejs/biome": "2.6.5",
@@ -72,6 +72,9 @@
72
72
  "@semantic-release/github": "^12.0.6",
73
73
  "@types/bun": "latest",
74
74
  "@types/node": "latest",
75
+ "@typescript-eslint/parser": "8.72.2",
76
+ "eslint": "9.39.5",
77
+ "eslint-plugin-sonarjs": "3.0.5",
75
78
  "husky": "^9.1.7",
76
79
  "jscpd": "4.2.3",
77
80
  "knip": "^6.9.0",