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: add TypeScript plugin #902

Draft
wants to merge 54 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
0a75f47
feat: add TypeScript plugin
BioPhoton Dec 23, 2024
63a3129
wip
BioPhoton Dec 23, 2024
1606175
wip
BioPhoton Dec 23, 2024
eead92f
wip
BioPhoton Dec 23, 2024
a92c487
wip
BioPhoton Dec 23, 2024
7abace2
fix lint
BioPhoton Dec 23, 2024
84b0bc6
fix format
BioPhoton Dec 23, 2024
01d044e
wip
BioPhoton Dec 23, 2024
e3c0d48
add category
BioPhoton Dec 23, 2024
7683533
fix: adjust plugin options
BioPhoton Dec 24, 2024
c1cff7b
fix: adjust plugin options for audits
BioPhoton Dec 24, 2024
62e4ba0
wip
BioPhoton Dec 24, 2024
0a48be4
wip
BioPhoton Dec 24, 2024
381ffbb
wip
BioPhoton Dec 24, 2024
a32f9b2
wip
BioPhoton Dec 24, 2024
c7f2d3a
wip
BioPhoton Dec 24, 2024
ba00774
wip
BioPhoton Dec 24, 2024
73232cd
add groups
BioPhoton Dec 25, 2024
ce4daa6
refactor static ts error data
BioPhoton Dec 25, 2024
68f56c8
feat(plugin-typescript): new tests, docs, readme, remove unused async…
aramirezj Dec 25, 2024
7c67433
merge PR
BioPhoton Dec 25, 2024
7ecb376
wip
BioPhoton Dec 25, 2024
8bd94f6
wip
BioPhoton Dec 25, 2024
e229455
wip
BioPhoton Dec 25, 2024
1b4d4bb
feat: add ts config default generator
BioPhoton Dec 26, 2024
cee894f
wip
BioPhoton Dec 26, 2024
e8ab0e4
wip
BioPhoton Dec 26, 2024
9ee6857
wip
BioPhoton Dec 26, 2024
f02dd08
wip
BioPhoton Dec 26, 2024
26c12d0
cleanup config and imports
BioPhoton Dec 26, 2024
4c71a2b
wip
BioPhoton Dec 27, 2024
233fe92
wip
BioPhoton Dec 27, 2024
039ed97
wip
BioPhoton Dec 27, 2024
bea7105
wip
BioPhoton Dec 27, 2024
05b2504
wip
BioPhoton Dec 27, 2024
1f17b67
wip
BioPhoton Dec 27, 2024
64876ed
wip
BioPhoton Dec 27, 2024
6f702d7
wip
BioPhoton Dec 27, 2024
58bb4f8
wip
BioPhoton Dec 27, 2024
d7d797c
wip
BioPhoton Dec 27, 2024
eda1681
chore(plugin-typescript): wip (#906)
aramirezj Dec 27, 2024
06b39ca
feat: add postinstall to typescript plugin
BioPhoton Dec 27, 2024
f6b8f59
wip
BioPhoton Dec 27, 2024
4ceac7f
fix lint
BioPhoton Dec 27, 2024
396b761
refactor tests
BioPhoton Dec 28, 2024
4092fa0
refactor unit tests
BioPhoton Dec 28, 2024
21ee2fe
refactor unit tests
BioPhoton Dec 28, 2024
1b0a8f3
wip
BioPhoton Dec 28, 2024
e855d6f
Update package.json
BioPhoton Dec 28, 2024
c150de0
wip
BioPhoton Dec 28, 2024
b3a38b3
test: setup basic e2e
BioPhoton Dec 28, 2024
430186e
wip
BioPhoton Dec 28, 2024
55f4e2c
wip
BioPhoton Dec 28, 2024
137fe52
wip
BioPhoton Dec 28, 2024
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
10 changes: 8 additions & 2 deletions code-pushup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
eslintCoreConfigNx,
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 @@ -33,10 +34,15 @@ const config: CoreConfig = {

export default mergeConfigs(
config,
await coverageCoreConfigNx(),
/* await coverageCoreConfigNx(),
await jsPackagesCoreConfig(),
await lighthouseCoreConfig(
'https://github.com/code-pushup/cli?tab=readme-ov-file#code-pushup-cli/',
),
await eslintCoreConfigNx(),
await eslintCoreConfigNx(),*/
await typescriptPluginConfigNx({
tsConfigPath:
'packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.json',
// onlyAudits: ['verbatim-module-syntax-typescript']
}),
);
23 changes: 23 additions & 0 deletions code-pushup.preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import jsPackagesPlugin from './packages/plugin-js-packages/src/index.js';
import lighthousePlugin, {
lighthouseGroupRef,
} from './packages/plugin-lighthouse/src/index.js';
import {
type TypescriptPluginOptions,
typescriptPlugin,
} from './packages/plugin-typescript/src/index.js';
import { getCategoryRefsFromGroups } from './packages/plugin-typescript/src/lib/utils.js';

export const jsPackagesCategories: CategoryConfig[] = [
{
Expand Down Expand Up @@ -129,6 +134,24 @@ export const eslintCoreConfigNx = async (
};
};

export const typescriptPluginConfigNx = async (
options?: TypescriptPluginOptions,
): Promise<CoreConfig> => {
const opt: TypescriptPluginOptions = {
...options,
};
return {
plugins: [await typescriptPlugin(opt)],
categories: [
{
slug: 'typescript',
title: 'Typescript',
refs: await getCategoryRefsFromGroups(opt),
},
],
};
};

export const coverageCoreConfigNx = async (
projectName?: string,
): Promise<CoreConfig> => {
Expand Down
9,053 changes: 4,242 additions & 4,811 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"scripts": {
"prepare": "husky install",
"commit": "git-cz",
"knip": "knip"
"knip": "knip",
"postinstall-plugin-typescript": "npx tsx --tsconfig=packages/plugin-typescript/tsconfig.tools.json packages/plugin-typescript/src/postinstall/index.ts",
BioPhoton marked this conversation as resolved.
Show resolved Hide resolved
"postinstall": "npm run postinstall-plugin-typescript"
},
"private": true,
"engines": {
Expand All @@ -25,7 +27,7 @@
"@code-pushup/portal-client": "^0.9.0",
"@isaacs/cliui": "^8.0.2",
"@nx/devkit": "19.8.13",
"@poppinss/cliui": "^6.4.1",
"@poppinss/cliui": "^6.4.2",
BioPhoton marked this conversation as resolved.
Show resolved Hide resolved
"@swc/helpers": "0.5.13",
"ansis": "^3.3.2",
"build-md": "^0.4.2",
Expand Down
169 changes: 169 additions & 0 deletions packages/plugin-typescript/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# @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 measure and track TypeScript compiler diagnostics in your TypeScript/JavaScript project.
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 -> 3
- `displayValue`: The number of issues found -> 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`).

Define the ts config file 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: [
// ...
typescriptPlugin({
tsConfigPath: './tsconfig.json',
onlyAudits: ['no-implicit-any'],
}),
],
};
```

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:

- Language and Environment - Configuration options for TypeScript language features and runtime environment, including decorators, JSX support, target ECMAScript version, and class field behaviors
- Interop Constraints - Settings that control how TypeScript interoperates with other JavaScript code, including module imports/exports and case sensitivity rules
- Watch Options - Configuration for TypeScript watch mode behavior, including file watching strategies and dependency tracking
- Project References - Options for managing TypeScript project references, composite projects, and build optimization settings
- Module Resolution - Settings that control how TypeScript finds and resolves module imports, including Node.js resolution, package.json exports/imports, and module syntax handling
- Type Checking Behavior - Configuration for TypeScript type checking strictness and error reporting, including property access rules and method override checking
- Control Flow Options - Settings that affect code flow analysis, including handling of unreachable code, unused labels, switch statements, and async/generator functions
- Strict Checks - Strict type checking options that enable additional compile-time verifications, including null checks, implicit any/this, and function type checking
- Build/Emit Options - Configuration options that control TypeScript output generation, including whether to emit files, how to handle comments and declarations, and settings for output optimization and compatibility helpers

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]()

## Plugin architecture

### Plugin configuration specification

The plugin accepts the following parameters:

| Option | Type | Default | Description |
| ------------ | -------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| tsConfigPath | 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 |

#### TsConfigPath

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

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

#### OnlyAudits

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

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

### Optionally set up categories

1. 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: 'no-implicit-any',
weight: 2,
},
{
type: 'audit',
plugin: 'typescript',
slug: 'no-explicit-any',
weight: 1,
},
// ...
],
},
// ...
];
```

Also groups can be used:

```ts
// ...
categories: [
{
slug: 'typescript',
title: 'TypeScript',
refs: [
{
slug: 'language-and-environment',
weight: 1,
type: 'group',
plugin: 'typescript',
},
Comment on lines +158 to +163
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we should mention the helper

// ...
],
},
// ...
];
```
21 changes: 21 additions & 0 deletions packages/plugin-typescript/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import tseslint from 'typescript-eslint';
import baseConfig from '../../eslint.config.js';

export default tseslint.config(
...baseConfig,
{
files: ['**/*.ts', '!**/mocks'],
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
{
files: ['**/*.json'],
rules: {
'@nx/dependency-checks': 'error',
},
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Error Code: 2307
* Compiler Option: moduleResolution
* Description: Cannot find module.
*/
import { nonExistentModule } from './non-existent';
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Error Code: 2322
* Compiler Option: strictNullChecks
* Description: Type 'number' is not assignable to type 'string'.
*/
function strictNullChecksError() {
let value: string = 42; // Error: Type 'number' is not assignable to type 'string'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@


/**
* Error Code: 7006
* Compiler Option: noImplicitAny
* Description: Parameter 'param' implicitly has an 'any' type.
*/
function noImplicitAnyError(param) {
console.log(param);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Error Code: 7027
* Compiler Option: strictPropertyInitialization
* Description: Property has no initializer and is not definitely assigned in the constructor.
*/
class strictPropertyInitializationError {
property: string; // Error: Property 'property' has no initializer
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"compilerOptions": {
"rootDir": "./src",
"strict": true,
"target": "ES6",
"module": "CommonJS"
},
"exclude": ["src/**/*.ts", "src/**/*.js"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"rootDir": "./src",
"strict": true,
"verbatimModuleSyntax": false,
"target": "ES6",
"module": "CommonJSsss"
},
"include": ["src/**/*.ts", "src/**/*.js"],
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Error Code: 7006
* Compiler Option: noImplicitAny
* Description: Parameter 'param' implicitly has an 'any' type.
*/
function noImplicitAnyError(param) {
console.log(param);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"rootDir": "./src",
"target": "ES6",
"module": "CommonJS"
},
"include": ["src/**/*.ts"],
}
Loading
Loading