Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(plugin-typescript): adjust logic #975

Merged
merged 18 commits into from
Mar 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions code-pushup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
jsDocsCoreConfig,
jsPackagesCoreConfig,
lighthouseCoreConfig,
typescriptPluginConfigNx,
} from './code-pushup.preset.js';
import type { CoreConfig } from './packages/models/src/index.js';
import { mergeConfigs } from './packages/utils/src/index.js';
Expand Down Expand Up @@ -39,6 +40,9 @@ export default mergeConfigs(
await lighthouseCoreConfig(
'https://github.com/code-pushup/cli?tab=readme-ov-file#code-pushup-cli/',
),
await typescriptPluginConfigNx({
tsconfig: 'packages/cli/tsconfig.lib.json',
}),
await eslintCoreConfigNx(),
jsDocsCoreConfig([
'packages/**/src/**/*.ts',
Expand Down
12 changes: 12 additions & 0 deletions code-pushup.preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ import { filterGroupsByOnlyAudits } from './packages/plugin-jsdocs/src/lib/utils
import lighthousePlugin, {
lighthouseGroupRef,
} from './packages/plugin-lighthouse/src/index.js';
import {
type TypescriptPluginOptions,
getCategories,
typescriptPlugin,
} from './packages/plugin-typescript/src/index.js';

export const jsPackagesCategories: CategoryConfig[] = [
{
Expand Down Expand Up @@ -168,6 +173,13 @@ export const eslintCoreConfigNx = async (
};
};

export const typescriptPluginConfigNx = async (
options?: TypescriptPluginOptions,
): Promise<CoreConfig> => ({
plugins: [await typescriptPlugin(options)],
categories: getCategories(),
});

export const coverageCoreConfigNx = async (
projectName?: string,
): Promise<CoreConfig> => {
Expand Down
164 changes: 164 additions & 0 deletions packages/plugin-typescript/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# @code-pushup/typescript-plugin

[![npm](https://img.shields.io/npm/v/%40code-pushup%2Ftypescript-plugin.svg)](https://www.npmjs.com/package/@code-pushup/typescript-plugin)
[![downloads](https://img.shields.io/npm/dm/%40code-pushup%2Ftypescript-plugin)](https://npmtrends.com/@code-pushup/typescript-plugin)
[![dependencies](https://img.shields.io/librariesio/release/npm/%40code-pushup/typescript-plugin)](https://www.npmjs.com/package/@code-pushup/typescript-plugin?activeTab=dependencies)

🕵️ **Code PushUp plugin for measuring TypeScript quality with compiler diagnostics.** 🔥

This plugin allows you to **incrementally adopt strict compilation flags in TypeScript projects**.
It analyzes your codebase using the TypeScript compiler to detect potential issues and configuration problems.

TypeScript compiler diagnostics are mapped to Code PushUp audits in the following way:

- `value`: The number of issues found for a specific TypeScript configuration option (e.g. 3)
- `displayValue`: The number of issues found (e.g. "3 issues")
- `score`: Binary scoring - 1 if no issues are found, 0 if any issues exist
- Issues are mapped to audit details, containing:
- Source file location
- Error message from TypeScript compiler
- Code reference where the issue was found

## Getting started

1. If you haven't already, install [@code-pushup/cli](../cli/README.md) and create a configuration file.

2. Install as a dev dependency with your package manager:

```sh
npm install --save-dev @code-pushup/typescript-plugin
```

```sh
yarn add --dev @code-pushup/typescript-plugin
```

```sh
pnpm add --save-dev @code-pushup/typescript-plugin
```

3. Add this plugin to the `plugins` array in your Code PushUp CLI config file (e.g. `code-pushup.config.ts`).

By default, a root `tsconfig.json` is used to compile your codebase. Based on those compiler options, the plugin will generate audits.

```ts
import typescriptPlugin from '@code-pushup/typescript-plugin';

export default {
// ...
plugins: [
// ...
await typescriptPlugin(),
],
};
```

4. Run the CLI with `npx code-pushup collect` and view or upload the report (refer to [CLI docs](../cli/README.md)).

## About TypeScript checks

The TypeScript plugin analyzes your codebase using the TypeScript compiler to identify potential issues and enforce best practices.
It helps ensure type safety and maintainability of your TypeScript code.

The plugin provides multiple audits grouped into different sets:

- _Semantic Errors_: `semantic-errors` - Errors that occur during type checking and type inference
- _Syntax Errors_: `syntax-errors` - Errors that occur during parsing and lexing of TypeScript source code
- _Configuration Errors_: `configuration-errors` - Errors that occur when parsing TypeScript configuration files
- _Declaration and Language Service Errors_: `declaration-and-language-service-errors` - Errors that occur during TypeScript language service operations
- _Internal Errors_: `internal-errors` - Errors that occur during TypeScript internal operations
- _No Implicit Any Errors_: `no-implicit-any-errors` - Errors related to `noImplicitAny` compiler option
- _Unknown Codes_: `unknown-codes` - Errors that do not match any known TypeScript error code

Each audit:

- Checks for specific TypeScript compiler errors and warnings
- Provides a score based on the number of issues found
- Includes detailed error messages and locations

Each set is also available as group in the plugin. See more under [Audits and Groups](./docs/audits-and-groups.md).

## Plugin architecture

### Plugin configuration specification

The plugin accepts the following parameters:

| Option | Type | Default | Description |
| ---------- | -------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| tsconfig | string | `tsconfig.json` | A string that defines the path to your `tsconfig.json` file |
| onlyAudits | string[] | undefined | An array of audit slugs to specify which documentation types you want to measure. Only the specified audits will be included in the results |

#### `tsconfig`

Optional parameter. The `tsconfig` option accepts a string that defines the path to your config file and defaults to `tsconfig.json`.

```js
await typescriptPlugin({
tsconfig: './tsconfig.json',
});
```

#### `onlyAudits`

The `onlyAudits` option allows you to specify which documentation types you want to measure. Only the specified audits will be included in the results. All audits are included by default. Example:

```js
await typescriptPlugin({
onlyAudits: ['no-implicit-any'],
});
```

### Optionally set up categories

Reference audits (or groups) which you wish to include in custom categories (use `npx code-pushup print-config` to list audits and groups).

Assign weights based on what influence each TypeScript checks should have on the overall category score (assign weight 0 to only include as extra info, without influencing category score).

```ts
// ...
categories: [
{
slug: 'typescript',
title: 'TypeScript',
refs: [
{
type: 'audit',
plugin: 'typescript',
slug: 'semantic-errors',
weight: 2,
},
{
type: 'audit',
plugin: 'typescript',
slug: 'syntax-errors',
weight: 1,
},
// ...
],
},
// ...
];
```

Also groups can be used:

```ts
// ...
categories: [
{
slug: 'typescript',
title: 'TypeScript',
refs: [
{
slug: 'language-and-environment',
weight: 1,
type: 'group',
plugin: 'typescript',
},
// ...
],
},
// ...
];
```
186 changes: 186 additions & 0 deletions packages/plugin-typescript/docs/audits-and-groups.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# 📚 Audits and Groups

The TypeScript plugin analyzes your codebase using the TypeScript compiler to identify potential issues and enforce best practices.

---

## 🛡️ Audits Overview

The plugin manages issues through structured audits and groups. Each audit targets a specific type of error, ensuring comprehensive analysis.

| **Audit** | **Slug** |
| ------------------------------------------- | ----------------------------------------- |
| **Semantic Errors** | `semantic-errors` |
| **Syntax Errors** | `syntax-errors` |
| **Configuration Errors** | `configuration-errors` |
| **Declaration and Language Service Errors** | `declaration-and-language-service-errors` |
| **Internal Errors** | `internal-errors` |
| **No Implicit Any Errors** | `no-implicit-any-errors` |
| **Unknown Codes** | `unknown-codes` |

---

### Semantic Errors - `semantic-errors`

Errors that occur during type checking and type inference.

- **Slug:** `semantic-errors`
- **Title:** Semantic Errors
- **Description:** Errors that occur during type checking and type inference.
- **Scoring:** The score is based on the number of issues found.
- **Value:** The value is the number of issues found.
- **Display Value:** The display value is the number of issues found.

#### Issues

| Severity | Message | Source file | Line(s) |
| :--------: | :----------------------------------------------------------------------------------- | :------------------------------------------------------------------------ | :-----: |
| 🚨 _error_ | TS2307: Cannot find module './non-existent' or its corresponding type declarations. | [`path/to/module-resolution.ts`](../path/to/module-resolution.ts) | 2 |
| 🚨 _error_ | TS2349: This expression is not callable.<br /> Type 'Number' has no call signatures. | [`path/to/strict-function-types.ts`](../path/to/strict-function-types.ts) | 3 |
| 🚨 _error_ | TS2304: Cannot find name 'NonExistentType'. | [`path/to/cannot-find-module.ts`](../path/to/cannot-find-module.ts) | 1 |

---

### Syntax Errors - `syntax-errors`

Errors that occur during parsing and lexing of TypeScript source code.

- **Slug:** `syntax-errors`
- **Title:** Syntax Errors
- **Description:** Errors that occur during parsing and lexing of TypeScript source code.
- **Scoring:** The score is based on the number of issues found.
- **Value:** The value is the number of issues found.
- **Display Value:** The display value is the number of issues found.

#### Issues

| Severity | Message | Source file | Line(s) |
| :--------: | :------------------------------------ | :------------------------------------------------------ | :-----: |
| 🚨 _error_ | TS1136: Property assignment expected. | [`path/to/syntax-error.ts`](../path/to/syntax-error.ts) | 1 |

---

### Configuration Errors - `configuration-errors`

Errors that occur when parsing TypeScript configuration files.

- **Slug:** `configuration-errors`
- **Title:** Configuration Errors
- **Description:** Errors that occur when parsing TypeScript configuration files.
- **Scoring:** The score is based on the number of issues found.
- **Value:** The value is the number of issues found.
- **Display Value:** The display value is the number of issues found.

#### Issues

| Severity | Message | Source file | Line(s) |
| :--------: | :----------------------------------------- | :-------------------------------------------------- | :-----: |
| 🚨 _error_ | TS5023: Unknown compiler option 'invalid'. | [`path/to/tsconfig.json`](../path/to/tsconfig.json) | 1 |

---

### Declaration and Language Service Errors - `declaration-and-language-service-errors`

Errors that occur during TypeScript language service operations.

- **Slug:** `declaration-and-language-service-errors`
- **Title:** Declaration and Language Service Errors
- **Description:** Errors that occur during TypeScript language service operations.
- **Scoring:** The score is based on the number of issues found.
- **Value:** The value is the number of issues found.
- **Display Value:** The display value is the number of issues found.

#### Issues

| Severity | Message | Source file | Line(s) |
| :--------: | :------------------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------------ | :-----: |
| 🚨 _error_ | TS4112: This member cannot have an 'override' modifier because its containing class 'Standalone' does not extend another class. | [`path/to/incorrect-modifier.ts`](../path/to/incorrect-modifier.ts) | 2 |

---

### Internal Errors - `internal-errors`

Errors that occur during TypeScript internal operations.

- **Slug:** `internal-errors`
- **Title:** Internal Errors
- **Description:** Errors that occur during TypeScript internal operations.
- **Scoring:** The score is based on the number of issues found.
- **Value:** The value is the number of issues found.
- **Display Value:** The display value is the number of issues found.

#### Issues

| Severity | Message | Source file | Line(s) |
| :--------: | :------------------------------- | :---------------------------------------------------------- | :-----: |
| 🚨 _error_ | TS9001: Internal compiler error. | [`path/to/internal-error.ts`](../path/to/internal-error.ts) | 4 |

---

### No Implicit Any Errors - `no-implicit-any-errors`

Errors related to no implicit any compiler option.

- **Slug:** `no-implicit-any-errors`
- **Title:** No Implicit Any Errors
- **Description:** Errors related to no implicit any compiler option.
- **Scoring:** The score is based on the number of issues found.
- **Value:** The value is the number of issues found.
- **Display Value:** The display value is the number of issues found.

#### Issues

| Severity | Message | Source file | Line(s) |
| :--------: | :-------------------------------------------------- | :------------------------------------------------------ | :-----: |
| 🚨 _error_ | TS7006: Parameter 'x' implicitly has an 'any' type. | [`path/to/implicit-any.ts`](../path/to/implicit-any.ts) | 5 |

---

### Unknown Codes - `unknown-codes`

Errors that do not match any known TypeScript error code.

- **Slug:** `unknown-codes`
- **Title:** Unknown Codes
- **Description:** Errors that do not match any known TypeScript error code.
- **Scoring:** The score is based on the number of issues found.
- **Value:** The value is the number of issues found.
- **Display Value:** The display value is the number of issues found.

#### Issues

| Severity | Message | Source file | Line(s) |
| :--------: | :-------------------------------------- | :-------------------------------------------------------- | :-----: |
| 🚨 _error_ | TS9999: Unknown error code encountered. | [`path/to/unknown-error.ts`](../path/to/unknown-error.ts) | 6 |

---

## 📂 Groups Overview

| **Group** | **Slug** |
| ----------------- | ------------------ |
| **Problems** | `problems` |
| **Configuration** | `ts-configuration` |
| **Miscellaneous** | `miscellaneous` |

### Problems - `problems`

- **Description:** Syntax, semantic, and internal compiler errors are critical for identifying and preventing bugs.
- **References:**
- Syntax Errors (`syntax-errors`)
- Semantic Errors (`semantic-errors`)
- No Implicit Any Errors (`no-implicit-any-errors`)

### Configuration - `ts-configuration`

- **Description:** Ensures correct TypeScript project setup, minimizing risks from misconfiguration.
- **References:**
- Configuration Errors (`configuration-errors`)

### Miscellaneous - `miscellaneous`

- **Description:** Informational errors that may not impact development directly but are helpful for deeper insights.
- **References:**
- Unknown Codes (`unknown-codes`)
- Internal Errors (`internal-errors`)
- Declaration and Language Service Errors (`declaration-and-language-service-errors`)
Loading