Compare commits
14 Commits
02fe9f4799
...
inline
Author | SHA1 | Date | |
---|---|---|---|
179cf83891 | |||
fb50ede688 | |||
51455e3c21 | |||
1d955d951d | |||
8ba9b0725a | |||
4d2762de39 | |||
19b07691fc | |||
4c67de9f72 | |||
9ea078f414 | |||
ba2671d760 | |||
d8f224c5cf | |||
690b46fd2b | |||
4563047e01 | |||
3ec7c342ba |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
!/packages/eslint-plugin-react-hooks
|
||||
/react
|
||||
src/types/rules
|
||||
|
||||
dist/**/*.js
|
||||
dist/**/*.js.map
|
||||
|
@ -1,7 +1,9 @@
|
||||
# eslint-rules
|
||||
|
||||
Personal ESLint config. Guaranteed to have no useless polyfills.
|
||||
|
||||
## flat config support
|
||||
|
||||
- ❌ [import](https://github.com/import-js/eslint-plugin-import/issues/2556)
|
||||
- ✅ [react](https://github.com/jsx-eslint/eslint-plugin-react/pull/3429)
|
||||
- 🇵🇷 [a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/pull/891)
|
||||
- ⏱️ [a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/pull/891)
|
||||
|
6
build.sh
6
build.sh
@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
./src/build-local-rules.ts
|
||||
npx dts-bundle-generator "./src/index.ts" -o "./dist/index.d.ts" --project "./tsconfig.build.json" --no-check
|
||||
# printf "\nimport './types.d';" >> "./dist/index.d.ts"
|
||||
NODE_ENV=production ./esbuild.ts
|
||||
sed -i '' '/import.*redirect.*;/d' "dist/index.d.ts"
|
1
dist/.npmrc
vendored
Normal file
1
dist/.npmrc
vendored
Normal file
@ -0,0 +1 @@
|
||||
shamefully-hoist=true
|
34
dist/index.d.ts
vendored
34
dist/index.d.ts
vendored
@ -1,5 +1,7 @@
|
||||
// Generated by dts-bundle-generator v8.1.2
|
||||
// Generated by dts-bundle-generator v9.4.0
|
||||
|
||||
import { ESLintUtils } from '@typescript-eslint/utils';
|
||||
import { Rule } from 'eslint';
|
||||
import { ESLintConfig, Rules } from 'eslint-define-config';
|
||||
|
||||
export declare const error = "error";
|
||||
@ -24,23 +26,47 @@ export interface LocalRuleOptions {
|
||||
"rules/no-empty-object-literal": RuleEntry<unknown>;
|
||||
}
|
||||
export type RuleOptions = Rules & Partial<LocalRuleOptions>;
|
||||
export interface CustomRule {
|
||||
rule: () => Promise<{
|
||||
default: Rule.RuleModule | ESLintUtils.RuleModule<string, unknown[]>;
|
||||
}>;
|
||||
options?: RuleLevel;
|
||||
}
|
||||
/**
|
||||
* ESLint Configuration.
|
||||
* @see [ESLint Configuration](https://eslint.org/docs/latest/user-guide/configuring/)
|
||||
*/
|
||||
export type Config = Omit<ESLintConfig, "rules"> & {
|
||||
export type InputConfig = Omit<ESLintConfig, "rules"> & {
|
||||
/**
|
||||
* Rules.
|
||||
* @see [Rules](https://eslint.org/docs/latest/user-guide/configuring/rules)
|
||||
*/
|
||||
rules?: RuleOptions;
|
||||
/**
|
||||
* Glob pattern to find paths to custom rule files in JavaScript or TypeScript.
|
||||
* Note this must be a string literal or an array of string literals since
|
||||
* this is statically analyzed.
|
||||
*/
|
||||
customRuleFiles?: string | string[];
|
||||
};
|
||||
/**
|
||||
* Returns a ESLint config object.
|
||||
*
|
||||
* By default, it includes `["@typescript-eslint", "import", "prettier"]` configs.
|
||||
* Additional bundled plugins include `["react", "react-refresh", "jsx-a11y", "unicorn"]`.
|
||||
* Additional bundled plugins include:
|
||||
*
|
||||
* 1. [`react`](https://github.com/jsx-eslint/eslint-plugin-react#list-of-supported-rules)
|
||||
* (automatically enables
|
||||
* [`react-hooks`](https://github.com/facebook/react/tree/main/packages/eslint-plugin-react-hooks))
|
||||
* 2. [`react-refresh`](https://github.com/ArnaudBarre/eslint-plugin-react-refresh)
|
||||
* 3. [`jsx-a11y`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y#supported-rules)
|
||||
* 4. [`unicorn`](https://github.com/sindresorhus/eslint-plugin-unicorn#rules)
|
||||
* 5. [`n`](https://github.com/eslint-community/eslint-plugin-n#-rules) (Node.js specific)
|
||||
* 6. [`jsdoc`](https://github.com/gajus/eslint-plugin-jsdoc#rules)
|
||||
*
|
||||
* Non bundled:
|
||||
* 1. [`graphql`](https://the-guild.dev/graphql/eslint/rules)
|
||||
*/
|
||||
export declare function extendConfig({ plugins, settings, rules, extends: _extends, overrides, ...rest }?: Config): ESLintConfig;
|
||||
export declare function extendConfig(of?: InputConfig): ESLintConfig;
|
||||
|
||||
export {};
|
||||
|
4
dist/overrides/is-core-module/package.json
vendored
Normal file
4
dist/overrides/is-core-module/package.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "is-core-module",
|
||||
"version": "2.13.1"
|
||||
}
|
4
dist/overrides/supports-preserve-symlinks-flag/package.json
vendored
Normal file
4
dist/overrides/supports-preserve-symlinks-flag/package.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "supports-preserve-symlinks-flag",
|
||||
"version": "1.0.0"
|
||||
}
|
56
dist/package.json
vendored
56
dist/package.json
vendored
@ -1,44 +1,60 @@
|
||||
{
|
||||
"name": "@aet/eslint-rules",
|
||||
"version": "0.0.8",
|
||||
"version": "0.0.24-beta.1",
|
||||
"license": "UNLICENSED",
|
||||
"peerDependencies": {
|
||||
"eslint": "^8.53.0",
|
||||
"typescript": "^5.2.2"
|
||||
"eslint": "^8.57.0",
|
||||
"typescript": "^5.4.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.4.0",
|
||||
"@types/eslint": "^8.44.7",
|
||||
"@typescript-eslint/eslint-plugin": "^6.12.0",
|
||||
"@typescript-eslint/parser": "^6.12.0",
|
||||
"@typescript-eslint/type-utils": "^6.12.0",
|
||||
"@typescript-eslint/utils": "^6.12.0",
|
||||
"@types/eslint": "^8.56.9",
|
||||
"@typescript-eslint/eslint-plugin": "^7.7.0",
|
||||
"@typescript-eslint/parser": "^7.7.0",
|
||||
"@typescript-eslint/type-utils": "^7.7.0",
|
||||
"@typescript-eslint/utils": "^7.7.0",
|
||||
"aria-query": "^5.3.0",
|
||||
"axe-core": "4.8.2",
|
||||
"axe-core": "^4.9.0",
|
||||
"axobject-query": "^4.0.0",
|
||||
"damerau-levenshtein": "1.0.8",
|
||||
"debug": "^4.3.4",
|
||||
"doctrine": "^3.0.0",
|
||||
"emoji-regex": "^10.3.0",
|
||||
"enhanced-resolve": "^5.15.0",
|
||||
"eslint-config-prettier": "9.0.0",
|
||||
"eslint-define-config": "^2.0.0",
|
||||
"enhanced-resolve": "^5.16.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-define-config": "^1.24.1",
|
||||
"eslint-import-resolver-node": "^0.3.9",
|
||||
"eslint-module-utils": "^2.8.0",
|
||||
"eslint-plugin-es-x": "7.4.0",
|
||||
"eslint-plugin-unicorn": "^49.0.0",
|
||||
"eslint-module-utils": "^2.8.1",
|
||||
"eslint-plugin-es-x": "^7.6.0",
|
||||
"eslint-plugin-jsdoc": "^48.2.3",
|
||||
"eslint-plugin-unicorn": "^52.0.0",
|
||||
"esprima": "^4.0.1",
|
||||
"esquery": "^1.5.0",
|
||||
"estraverse": "^5.3.0",
|
||||
"fast-glob": "^3.3.2",
|
||||
"get-tsconfig": "^4.7.2",
|
||||
"ignore": "^5.3.0",
|
||||
"get-tsconfig": "^4.7.3",
|
||||
"ignore": "^5.3.1",
|
||||
"is-builtin-module": "^3.2.1",
|
||||
"is-core-module": "^2.13.1",
|
||||
"is-glob": "^4.0.3",
|
||||
"language-tags": "^1.0.9",
|
||||
"lodash": "^4.17.21",
|
||||
"minimatch": "^9.0.3",
|
||||
"minimatch": "^9.0.4",
|
||||
"resolve": "^2.0.0-next.5",
|
||||
"semver": "^7.5.4",
|
||||
"semver": "^7.6.0",
|
||||
"tsconfig-paths": "^4.2.0"
|
||||
},
|
||||
"overrides": {
|
||||
"supports-preserve-symlinks-flag": "file:./overrides/supports-preserve-symlinks-flag",
|
||||
"is-core-module": "file:./overrides/is-core-module"
|
||||
},
|
||||
"resolutions": {
|
||||
"**/supports-preserve-symlinks-flag": "file:./overrides/supports-preserve-symlinks-flag",
|
||||
"**/is-core-module": "file:./overrides/is-core-module"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"supports-preserve-symlinks-flag": "file:./overrides/supports-preserve-symlinks-flag",
|
||||
"is-core-module": "file:./overrides/is-core-module"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
13
dist/prettier.d.ts
vendored
Normal file
13
dist/prettier.d.ts
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
// Generated by dts-bundle-generator v9.4.0
|
||||
|
||||
import { Config } from 'prettier';
|
||||
|
||||
declare function defineConfig({ tailwind, ...config }: Partial<Config> & {
|
||||
tailwind?: boolean;
|
||||
}): Config;
|
||||
|
||||
export {
|
||||
defineConfig as default,
|
||||
};
|
||||
|
||||
export {};
|
16
dist/types.d.ts
vendored
Normal file
16
dist/types.d.ts
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
// Generated by dts-bundle-generator v9.4.0
|
||||
|
||||
import { ESLintUtils } from '@typescript-eslint/utils';
|
||||
import { Rule } from 'eslint';
|
||||
|
||||
export declare function defineRules(rules: {
|
||||
[ruleName: string]: Rule.RuleModule | ESLintUtils.RuleModule<string, unknown[]>;
|
||||
}): {
|
||||
[ruleName: string]: Rule.RuleModule | ESLintUtils.RuleModule<string, unknown[], ESLintUtils.RuleListener>;
|
||||
};
|
||||
export declare function defineRule({ name, create, ...meta }: Rule.RuleMetaData & {
|
||||
name?: string;
|
||||
create: (context: Rule.RuleContext) => Rule.RuleListener;
|
||||
}): Rule.RuleModule;
|
||||
|
||||
export {};
|
1130
dist/yarn.lock
vendored
Normal file
1130
dist/yarn.lock
vendored
Normal file
File diff suppressed because it is too large
Load Diff
66
package.json
66
package.json
@ -1,42 +1,49 @@
|
||||
{
|
||||
"name": "@aet/eslint-configs",
|
||||
"scripts": {
|
||||
"build": "./build.sh",
|
||||
"check-import": "./src/check-imports.ts"
|
||||
"build": "./scripts/build-all.ts",
|
||||
"build-types": "cd ./packages/eslint-define-config && ./scripts/index.ts",
|
||||
"check-import": "./scripts/check-imports.ts"
|
||||
},
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.23.3",
|
||||
"@babel/plugin-transform-flow-strip-types": "^7.23.3",
|
||||
"@babel/preset-env": "^7.23.3",
|
||||
"@babel/core": "^7.24.4",
|
||||
"@babel/plugin-transform-flow-strip-types": "^7.24.1",
|
||||
"@babel/preset-env": "^7.24.4",
|
||||
"@types/babel-plugin-macros": "^3.1.3",
|
||||
"@types/babel__core": "^7.20.5",
|
||||
"@types/eslint": "^8.44.7",
|
||||
"@types/eslint": "^8.56.10",
|
||||
"@types/esprima": "^4.0.6",
|
||||
"@types/esquery": "^1.5.3",
|
||||
"@types/estree": "^1.0.5",
|
||||
"@types/estree-jsx": "^1.0.3",
|
||||
"@types/lodash": "^4.14.202",
|
||||
"@types/node": "^20.9.3",
|
||||
"@typescript-eslint/eslint-plugin": "6.12.0",
|
||||
"@typescript-eslint/type-utils": "^6.12.0",
|
||||
"@typescript-eslint/types": "^6.12.0",
|
||||
"@typescript-eslint/typescript-estree": "^6.12.0",
|
||||
"@typescript-eslint/utils": "^6.12.0",
|
||||
"@types/estree-jsx": "^1.0.5",
|
||||
"@types/lodash": "^4.17.0",
|
||||
"@types/node": "^20.12.7",
|
||||
"@typescript-eslint/eslint-plugin": "7.7.0",
|
||||
"@typescript-eslint/type-utils": "^7.7.0",
|
||||
"@typescript-eslint/types": "^7.7.0",
|
||||
"@typescript-eslint/typescript-estree": "^7.7.0",
|
||||
"@typescript-eslint/utils": "^7.7.0",
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"dts-bundle-generator": "^8.1.2",
|
||||
"dts-bundle-generator": "^9.5.0",
|
||||
"esbin": "0.0.4",
|
||||
"esbuild": "0.19.7",
|
||||
"esbuild": "0.20.2",
|
||||
"esbuild-plugin-alias": "^0.2.1",
|
||||
"eslint": "8.54.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-define-config": "^1.24.1",
|
||||
"eslint": "8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-define-config": "file:./src/types",
|
||||
"esprima": "^4.0.1",
|
||||
"esquery": "^1.5.0",
|
||||
"fast-glob": "^3.3.2",
|
||||
"json-schema-to-ts": "^2.9.2",
|
||||
"find-cache-dir": "^5.0.0",
|
||||
"json-schema-to-ts": "^3.0.1",
|
||||
"lodash": "^4.17.21",
|
||||
"minimatch": "^9.0.3",
|
||||
"minimatch": "^9.0.4",
|
||||
"patch-package": "^8.0.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"prettier": "^3.1.0",
|
||||
"prettier": "^3.2.5",
|
||||
"prop-types": "^15.8.1",
|
||||
"typescript": "5.3.2"
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
"prettier": {
|
||||
"arrowParens": "avoid",
|
||||
@ -45,5 +52,18 @@
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"function-bind": "npm:@nolyfill/function-bind@latest",
|
||||
"has-proto": "npm:@nolyfill/has-proto@latest",
|
||||
"has-symbols": "npm:@nolyfill/has-symbols@latest",
|
||||
"hasown": "npm:@nolyfill/hasown@latest",
|
||||
"isarray": "npm:@nolyfill/isarray@latest",
|
||||
"jsonify": "npm:@nolyfill/jsonify@latest",
|
||||
"object-keys": "npm:@nolyfill/object-keys@latest",
|
||||
"set-function-length": "npm:@nolyfill/set-function-length@latest",
|
||||
"@babel/types": "7.24.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
21
packages/eslint-define-config/LICENSE
Normal file
21
packages/eslint-define-config/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-2023 Christopher Quadflieg
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
144
packages/eslint-define-config/README.md
Normal file
144
packages/eslint-define-config/README.md
Normal file
@ -0,0 +1,144 @@
|
||||
<p>
|
||||
<a href="https://www.npmjs.com/package/eslint-define-config" target="_blank">
|
||||
<img alt="NPM package" src="https://img.shields.io/npm/v/eslint-define-config.svg">
|
||||
</a>
|
||||
<a href="https://www.npmjs.com/package/eslint-define-config" target="_blank">
|
||||
<img alt="Downloads" src="https://img.shields.io/npm/dt/eslint-define-config.svg">
|
||||
</a>
|
||||
<a href="https://github.com/eslint-types/eslint-define-config/actions/workflows/ci.yml">
|
||||
<img alt="Build Status" src="https://github.com/eslint-types/eslint-define-config/actions/workflows/ci.yml/badge.svg?branch=main">
|
||||
</a>
|
||||
<a href="https://github.com/eslint-types/eslint-define-config/blob/main/LICENSE">
|
||||
<img alt="License: MIT" src="https://img.shields.io/github/license/eslint-types/eslint-define-config.svg">
|
||||
</a>
|
||||
<a href="https://prettier.io" target="_blank">
|
||||
<img alt="Code Style: Prettier" src="https://img.shields.io/badge/code_style-prettier-ff69b4.svg">
|
||||
</a>
|
||||
<a href="https://www.paypal.com/donate?hosted_button_id=L7GY729FBKTZY" target="_blank">
|
||||
<img alt="Donate: PayPal" src="https://img.shields.io/badge/Donate-PayPal-blue.svg">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
# eslint-define-config
|
||||
|
||||
Provide a `defineConfig` function for `.eslintrc.js`, and a `defineFlatConfig` function for `eslint.config.js` files.
|
||||
|
||||
> This project is written by a human and only partially automatically generated!
|
||||
> Some rules are even enhanced by hand!
|
||||
> Unfortunately, this has the disadvantage that not everything is immediately defined. For example, if a rule is not defined, it falls back to a basic definition.
|
||||
> However, the advantage is that you get documentation for pretty much everything in the code and usually get a direct link to the respective plugin or eslint rule. The types are also strictly typed.
|
||||
>
|
||||
> So if you are missing something like a rule or a plugin that should also be supported or a rule definition is e.g. out of date, feel free to open an issue or PR for it.
|
||||
|
||||
# Installation
|
||||
|
||||
```bash
|
||||
# add eslint and eslint-define-config to project’s dev dependencies
|
||||
npm add --save-dev eslint eslint-define-config
|
||||
# or
|
||||
yarn add --dev eslint eslint-define-config
|
||||
# or
|
||||
pnpm add --save-dev eslint eslint-define-config
|
||||
```
|
||||
|
||||
# Usage
|
||||
|
||||
`.eslintrc.js`
|
||||
|
||||
```ts
|
||||
// @ts-check
|
||||
|
||||
// To activate auto-suggestions for Rules of specific plugins, you need to add a `/// <reference types="eslint-plugin-PLUGIN_NAME/define-config-support" />` comment.
|
||||
// ⚠️ This feature is very new and requires the support of the respective plugin owners.
|
||||
|
||||
/// <reference types="@typescript-eslint/eslint-plugin/define-config-support" />
|
||||
|
||||
const { defineConfig } = require('eslint-define-config');
|
||||
|
||||
module.exports = defineConfig({
|
||||
root: true,
|
||||
rules: {
|
||||
// rules...
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## Flat Config
|
||||
|
||||
`eslint.config.js`
|
||||
|
||||
```ts
|
||||
// @ts-check
|
||||
const { defineFlatConfig } = require('eslint-define-config');
|
||||
|
||||
module.exports = defineFlatConfig([
|
||||
'eslint:recommended',
|
||||
{
|
||||
plugins: {
|
||||
// plugins...
|
||||
},
|
||||
rules: {
|
||||
// rules...
|
||||
},
|
||||
},
|
||||
]);
|
||||
```
|
||||
|
||||
# Why?
|
||||
|
||||
Improve your eslint configuration experience with:
|
||||
|
||||
- auto-suggestions
|
||||
- type checking (Use `// @ts-check` at the first line in your `.eslintrc.js` or `eslint.config.js`)
|
||||
- documentation
|
||||
- deprecation warnings
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/7195563/112484789-8a416480-8d7a-11eb-9337-d8b5bc16de17.png" alt="Image" width="600px"/>
|
||||
|
||||
## Video
|
||||
|
||||
_Click on the thumbnail to play the video_
|
||||
|
||||
<a href="https://user-images.githubusercontent.com/7195563/112726158-4a19e780-8f1c-11eb-8cc6-4ea6c100137f.mp4" target="_blank">
|
||||
<img src="https://user-images.githubusercontent.com/7195563/112726343-30c56b00-8f1d-11eb-9b92-260c530caf1b.png" alt="Video" width="600px"/>
|
||||
</a>
|
||||
|
||||
## Want to support your own plugin?
|
||||
|
||||
:warning: **This feature is very new and requires the support of the respective plugin owners**
|
||||
|
||||
Add a `declare module` to your plugin package like this:
|
||||
|
||||
```ts
|
||||
declare module 'eslint-define-config' {
|
||||
export interface CustomRuleOptions {
|
||||
/**
|
||||
* Require consistently using either `T[]` or `Array<T>` for arrays.
|
||||
*
|
||||
* @see [array-type](https://typescript-eslint.io/rules/array-type)
|
||||
*/
|
||||
'@typescript-eslint/array-type': [
|
||||
{
|
||||
default?: 'array' | 'generic' | 'array-simple';
|
||||
readonly?: 'array' | 'generic' | 'array-simple';
|
||||
},
|
||||
];
|
||||
|
||||
// ... more Rules
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
There are other interfaces that can be extended.
|
||||
|
||||
- `CustomExtends`
|
||||
- `CustomParserOptions`
|
||||
- `CustomParsers`
|
||||
- `CustomPlugins`
|
||||
- `CustomSettings`
|
||||
|
||||
# Credits
|
||||
|
||||
- [Proposal Idea](https://github.com/eslint/eslint/issues/14249)
|
||||
- [Vite](https://github.com/vitejs/vite) and [Evan You](https://github.com/yyx990803) for the idea
|
||||
- [@antfu](https://github.com/antfu) and his [tweet](https://twitter.com/antfu7/status/1365907188338753536)
|
120
packages/eslint-define-config/package.json
Normal file
120
packages/eslint-define-config/package.json
Normal file
@ -0,0 +1,120 @@
|
||||
{
|
||||
"name": "eslint-define-config",
|
||||
"version": "1.24.1",
|
||||
"description": "Provide a defineConfig function for .eslintrc.js files",
|
||||
"scripts": {
|
||||
"clean": "rimraf coverage .eslintcache dist pnpm-lock.yaml node_modules",
|
||||
"format": "prettier --cache --write .",
|
||||
"lint:run": "eslint --cache --cache-strategy content --report-unused-disable-directives .",
|
||||
"lint": "run-s build lint:run",
|
||||
"typecheck": "vitest typecheck",
|
||||
"ts-check": "tsc",
|
||||
"test": "vitest",
|
||||
"coverage": "vitest run --coverage",
|
||||
"generate:rules": "tsx ./scripts/generate-rule-files/cli.ts",
|
||||
"prepublishOnly": "pnpm run clean && pnpm install && pnpm run build",
|
||||
"preflight": "pnpm install && run-s format lint ts-check test typecheck"
|
||||
},
|
||||
"type": "module",
|
||||
"main": "dist/index.cjs",
|
||||
"module": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"require": "./dist/index.cjs",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"keywords": [
|
||||
"config",
|
||||
"configuration",
|
||||
"define-config",
|
||||
"eslint-config",
|
||||
"eslint",
|
||||
"eslintconfig",
|
||||
"typed",
|
||||
"typescript"
|
||||
],
|
||||
"author": {
|
||||
"name": "Christopher Quadflieg",
|
||||
"email": "chrissi92@hotmail.de",
|
||||
"url": "https://github.com/Shinigami92"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/eslint-types/eslint-define-config.git"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/Shinigami92"
|
||||
},
|
||||
{
|
||||
"type": "paypal",
|
||||
"url": "https://www.paypal.com/donate/?hosted_button_id=L7GY729FBKTZY"
|
||||
}
|
||||
],
|
||||
"bugs": "https://github.com/eslint-types/eslint-define-config/issues",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"dist",
|
||||
"src",
|
||||
"tsconfig.json"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@graphql-eslint/eslint-plugin": "~3.20.1",
|
||||
"@intlify/eslint-plugin-vue-i18n": "~2.0.0",
|
||||
"@poppinss/cliui": "~6.4.1",
|
||||
"@types/dedent": "^0.7.2",
|
||||
"@types/eslint": "~8.44.3",
|
||||
"@types/json-schema": "~7.0.13",
|
||||
"@types/node": "~20.8.3",
|
||||
"@typescript-eslint/eslint-plugin": "~6.7.4",
|
||||
"@typescript-eslint/parser": "~6.7.4",
|
||||
"@vitest/coverage-v8": "~0.34.6",
|
||||
"change-case": "~5.4.4",
|
||||
"dedent": "^1.5.3",
|
||||
"eslint-config-prettier": "~9.0.0",
|
||||
"eslint-gitignore": "~0.1.0",
|
||||
"eslint-plugin-deprecation": "~2.0.0",
|
||||
"eslint-plugin-eslint-comments": "~3.2.0",
|
||||
"eslint-plugin-import": "~2.28.1",
|
||||
"eslint-plugin-inclusive-language": "~2.2.1",
|
||||
"eslint-plugin-jsdoc": "~46.8.2",
|
||||
"eslint-plugin-jsonc": "~2.9.0",
|
||||
"eslint-plugin-jsx-a11y": "~6.7.1",
|
||||
"eslint-plugin-mdx": "~3.1.5",
|
||||
"eslint-plugin-n": "~16.1.0",
|
||||
"eslint-plugin-node": "~11.1.0",
|
||||
"eslint-plugin-prettier": "~5.0.0",
|
||||
"eslint-plugin-promise": "~6.1.1",
|
||||
"eslint-plugin-react": "~7.33.2",
|
||||
"eslint-plugin-react-hooks": "~4.6.0",
|
||||
"eslint-plugin-sonarjs": "~0.21.0",
|
||||
"eslint-plugin-spellcheck": "~0.0.20",
|
||||
"eslint-plugin-testing-library": "~6.0.2",
|
||||
"eslint-plugin-unicorn": "~48.0.1",
|
||||
"eslint-plugin-vitest": "~0.3.2",
|
||||
"eslint-plugin-vue": "~9.17.0",
|
||||
"eslint-plugin-vue-pug": "~0.6.0",
|
||||
"eslint-plugin-yml": "~1.10.0",
|
||||
"expect-type": "~0.17.3",
|
||||
"graphql": "~16.8.1",
|
||||
"json-schema": "~0.4.0",
|
||||
"json-schema-to-ts": "~2.9.2",
|
||||
"json-schema-to-typescript": "~13.1.1",
|
||||
"npm-run-all": "~4.1.5",
|
||||
"prettier-plugin-organize-imports": "^3.2.4",
|
||||
"rimraf": "~5.0.5",
|
||||
"tsup": "~7.2.0",
|
||||
"vue-eslint-parser": "~9.3.2"
|
||||
},
|
||||
"packageManager": "pnpm@8.8.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0",
|
||||
"npm": ">=9.0.0",
|
||||
"pnpm": ">=8.6.0"
|
||||
}
|
||||
}
|
6894
packages/eslint-define-config/pnpm-lock.yaml
generated
Normal file
6894
packages/eslint-define-config/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,22 @@
|
||||
diff --git b/lib/rules/eslint/no-constructor-return.d.ts a/lib/rules/eslint/no-constructor-return.d.ts
|
||||
index fedeca4..3e1fd03 100644
|
||||
--- b/lib/rules/eslint/no-constructor-return.d.ts
|
||||
+++ a/lib/rules/eslint/no-constructor-return.d.ts
|
||||
@@ -1,16 +1,9 @@
|
||||
import type { RuleConfig } from '../rule-config';
|
||||
|
||||
-/**
|
||||
- * Option.
|
||||
- */
|
||||
-export interface NoConstructorReturnOption {
|
||||
- [k: string]: any;
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* Options.
|
||||
*/
|
||||
-export type NoConstructorReturnOptions = NoConstructorReturnOption;
|
||||
+export type NoConstructorReturnOptions = [];
|
||||
|
||||
/**
|
||||
* Disallow returning value from constructor.
|
@ -0,0 +1,14 @@
|
||||
diff --git b/lib/rules/graphql-eslint/naming-convention.d.ts a/lib/rules/graphql-eslint/naming-convention.d.ts
|
||||
index 60b228b..5e01373 100644
|
||||
--- b/lib/rules/graphql-eslint/naming-convention.d.ts
|
||||
+++ a/lib/rules/graphql-eslint/naming-convention.d.ts
|
||||
@@ -78,8 +78,7 @@ export type NamingConventionOption =
|
||||
VariableDefinition?: AsString | AsObject;
|
||||
allowLeadingUnderscore?: boolean;
|
||||
allowTrailingUnderscore?: boolean;
|
||||
- /**
|
||||
- */
|
||||
+ } & {
|
||||
[k: string]: AsString | AsObject;
|
||||
},
|
||||
];
|
@ -0,0 +1,13 @@
|
||||
diff --git b/lib/rules/node/file-extension-in-import.d.ts a/lib/rules/node/file-extension-in-import.d.ts
|
||||
index 652b18d..7261252 100644
|
||||
--- b/lib/rules/node/file-extension-in-import.d.ts
|
||||
+++ a/lib/rules/node/file-extension-in-import.d.ts
|
||||
@@ -5,7 +5,7 @@ import type { RuleConfig } from '../rule-config';
|
||||
*/
|
||||
export interface FileExtensionInImportConfig {
|
||||
tryExtensions?: string[];
|
||||
- [k: string]: 'always' | 'never';
|
||||
+ [ext: `.${string}`]: 'always' | 'never';
|
||||
}
|
||||
|
||||
/**
|
@ -0,0 +1,23 @@
|
||||
diff --git a/lib/rules/react/jsx-no-constructed-context-values.d.ts b/lib/rules/react/jsx-no-constructed-context-values.d.ts
|
||||
index 410f060..e356693 100644
|
||||
--- a/lib/rules/react/jsx-no-constructed-context-values.d.ts
|
||||
+++ b/lib/rules/react/jsx-no-constructed-context-values.d.ts
|
||||
@@ -1,17 +1,9 @@
|
||||
import type { RuleConfig } from '../rule-config';
|
||||
|
||||
-/**
|
||||
- * Option.
|
||||
- */
|
||||
-export interface JsxNoConstructedContextValuesOption {
|
||||
- [k: string]: any;
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* Options.
|
||||
*/
|
||||
-export type JsxNoConstructedContextValuesOptions =
|
||||
- JsxNoConstructedContextValuesOption;
|
||||
+export type JsxNoConstructedContextValuesOptions = [];
|
||||
|
||||
/**
|
||||
* Disallows JSX context provider values from taking values that will cause needless rerenders.
|
@ -0,0 +1,13 @@
|
||||
diff --git a/lib/rules/react/jsx-props-no-spreading.d.ts b/lib/rules/react/jsx-props-no-spreading.d.ts
|
||||
index c1e0069..ba1e1bc 100644
|
||||
--- a/lib/rules/react/jsx-props-no-spreading.d.ts
|
||||
+++ b/lib/rules/react/jsx-props-no-spreading.d.ts
|
||||
@@ -8,8 +8,6 @@ export type JsxPropsNoSpreadingOption = {
|
||||
custom?: 'enforce' | 'ignore';
|
||||
exceptions?: string[];
|
||||
[k: string]: any;
|
||||
-} & {
|
||||
- [k: string]: any;
|
||||
};
|
||||
|
||||
/**
|
@ -0,0 +1,21 @@
|
||||
diff --git a/lib/rules/vitest/valid-title.d.ts b/lib/rules/vitest/valid-title.d.ts
|
||||
index 160be76..834ac9b 100644
|
||||
--- a/lib/rules/vitest/valid-title.d.ts
|
||||
+++ b/lib/rules/vitest/valid-title.d.ts
|
||||
@@ -7,15 +7,7 @@ export interface ValidTitleOption {
|
||||
ignoreTypeOfDescribeName?: boolean;
|
||||
allowArguments?: boolean;
|
||||
disallowedWords?: string[];
|
||||
- /**
|
||||
- */
|
||||
- [k: string]:
|
||||
- | string
|
||||
- | [string]
|
||||
- | [string, string]
|
||||
- | {
|
||||
- [k: string]: string | [string] | [string, string];
|
||||
- };
|
||||
+ [k: string]: any;
|
||||
}
|
||||
|
||||
/**
|
178
packages/eslint-define-config/scripts/index.ts
Executable file
178
packages/eslint-define-config/scripts/index.ts
Executable file
@ -0,0 +1,178 @@
|
||||
#!/usr/bin/env bun
|
||||
import { Logger, colors as cliColors } from '@poppinss/cliui';
|
||||
import { pascalCase } from 'change-case';
|
||||
import type { Rule } from 'eslint';
|
||||
import { existsSync, promises as fs } from 'node:fs';
|
||||
import { join, resolve } from 'node:path';
|
||||
import { format } from 'prettier';
|
||||
import { buildJSDoc, prettierConfig, type Plugin } from './utils';
|
||||
import { PLUGIN_REGISTRY, loadPlugin } from './plugins-map';
|
||||
import { RuleFile } from './rule-file';
|
||||
|
||||
interface FailedRule {
|
||||
ruleName: string;
|
||||
err: unknown;
|
||||
}
|
||||
|
||||
const logger = new Logger();
|
||||
const colors = cliColors.ansi();
|
||||
|
||||
const getRuleName = (name: string) =>
|
||||
name === 'ESLint' ? 'ESLintRule' : `${pascalCase(name)}Rule`;
|
||||
|
||||
const index: [string, string][] = [];
|
||||
|
||||
/**
|
||||
* Generate the `index.d.ts` file for the plugin's rules that will re-export all rules.
|
||||
*/
|
||||
async function generateRuleIndexFile(
|
||||
pluginDirectory: string,
|
||||
{ rules, name, id }: Plugin,
|
||||
failedRules: FailedRule[],
|
||||
): Promise<void> {
|
||||
const generatedRules = Object.keys(rules!).filter(
|
||||
ruleName => !failedRules.some(failedRule => failedRule.ruleName === ruleName),
|
||||
);
|
||||
|
||||
/**
|
||||
* Build all the import statements for the rules.
|
||||
*/
|
||||
const rulesImports = generatedRules
|
||||
.map(name => `import type { ${getRuleName(name)} } from './${name}';`)
|
||||
.join('\n');
|
||||
|
||||
/**
|
||||
* Build the exported type that is an intersection of all the rules.
|
||||
*/
|
||||
const rulesFinalIntersection = generatedRules
|
||||
.map(name => `${getRuleName(name)}`)
|
||||
.sort()
|
||||
.join(' & ');
|
||||
|
||||
const pluginRulesType = `
|
||||
${buildJSDoc([`All ${name} rules.`])}
|
||||
export type ${name}Rules = ${rulesFinalIntersection};
|
||||
`;
|
||||
|
||||
/**
|
||||
* Write the final `index.d.ts` file.
|
||||
*/
|
||||
const fileContent = `
|
||||
${rulesImports}
|
||||
|
||||
${pluginRulesType}
|
||||
`;
|
||||
|
||||
const indexPath = join(pluginDirectory, 'index.d.ts');
|
||||
await fs.writeFile(indexPath, await format(fileContent, prettierConfig));
|
||||
|
||||
index.push([`${name}Rules`, `./${id}/index`]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a report after having generated rules files for a plugin.
|
||||
*/
|
||||
function printGenerationReport(
|
||||
rules: Array<[string, Rule.RuleModule]>,
|
||||
failedRules: FailedRule[],
|
||||
): void {
|
||||
const msg: string = ` ✅ Generated ${rules.length - failedRules.length} rules`;
|
||||
logger.logUpdate(colors.green(msg));
|
||||
logger.logUpdatePersist();
|
||||
|
||||
if (failedRules.length) {
|
||||
logger.log(colors.red(` ❌ Failed ${failedRules.length} rules`));
|
||||
failedRules.forEach(({ ruleName, err }) => {
|
||||
logger.log(colors.red(` - ${ruleName}: ${String(err)}`));
|
||||
});
|
||||
}
|
||||
|
||||
logger.log('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a `.d.ts` file for each rule in the given plugin.
|
||||
*/
|
||||
async function generateRulesFiles(
|
||||
plugin: Plugin,
|
||||
pluginDirectory: string,
|
||||
): Promise<{ failedRules: FailedRule[] }> {
|
||||
const failedRules: FailedRule[] = [];
|
||||
|
||||
const pluginRules = plugin.rules;
|
||||
if (!pluginRules) {
|
||||
throw new Error(
|
||||
`Plugin ${plugin.name} doesn't have any rules. Did you forget to load them?`,
|
||||
);
|
||||
}
|
||||
|
||||
const rules = Object.entries(pluginRules);
|
||||
for (const [ruleName, rule] of rules) {
|
||||
logger.logUpdate(colors.yellow(` Generating > ${ruleName}`));
|
||||
|
||||
try {
|
||||
await RuleFile(plugin, pluginDirectory, ruleName, rule);
|
||||
} catch (err) {
|
||||
failedRules.push({ ruleName, err });
|
||||
}
|
||||
}
|
||||
|
||||
printGenerationReport(rules, failedRules);
|
||||
|
||||
return { failedRules };
|
||||
}
|
||||
|
||||
const rulesDirectory = resolve(__dirname, '../../../src/types/rules');
|
||||
|
||||
/**
|
||||
* If it doesn't exist, create the directory that will contain the plugin's rule files.
|
||||
*/
|
||||
async function createPluginDirectory(pluginName: string): Promise<string> {
|
||||
const pluginDirectory = join(rulesDirectory, pluginName);
|
||||
|
||||
if (existsSync(pluginDirectory)) {
|
||||
await fs.rm(pluginDirectory, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
await fs.mkdir(pluginDirectory, { mode: 0o755, recursive: true });
|
||||
|
||||
return pluginDirectory;
|
||||
}
|
||||
|
||||
export interface RunOptions {
|
||||
plugins?: string[];
|
||||
targetDirectory?: string;
|
||||
}
|
||||
|
||||
for (const plugin of PLUGIN_REGISTRY) {
|
||||
logger.info(`Generating ${plugin.name} rules.`);
|
||||
logger.logUpdate(colors.yellow(` Loading plugin > ${plugin.name}`));
|
||||
const loadedPlugin = await loadPlugin(plugin);
|
||||
|
||||
const pluginDir = await createPluginDirectory(plugin.id);
|
||||
const { failedRules } = await generateRulesFiles(loadedPlugin, pluginDir);
|
||||
|
||||
await generateRuleIndexFile(pluginDir, loadedPlugin, failedRules);
|
||||
}
|
||||
|
||||
await fs.writeFile(
|
||||
resolve(rulesDirectory, 'index.d.ts'),
|
||||
await format(
|
||||
[
|
||||
'import type { RuleConfig } from "./rule-config";',
|
||||
...index.map(([name, path]) => `import { ${name} } from ${JSON.stringify(path)};`),
|
||||
'',
|
||||
'/**',
|
||||
' * Rules.',
|
||||
' *',
|
||||
' * @see [Rules](https://eslint.org/docs/user-guide/configuring/rules)',
|
||||
' */',
|
||||
'',
|
||||
'export type Rules = Partial<',
|
||||
...index.map(([name]) => ` ${name} &`),
|
||||
' Record<string, RuleConfig>',
|
||||
'>;',
|
||||
].join('\n'),
|
||||
prettierConfig,
|
||||
),
|
||||
);
|
58
packages/eslint-define-config/scripts/json-schema-to-ts.ts
Normal file
58
packages/eslint-define-config/scripts/json-schema-to-ts.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import type { JSONSchema4 } from 'json-schema';
|
||||
import { compile } from 'json-schema-to-typescript';
|
||||
|
||||
/**
|
||||
* Remove unnecessary comments that are generated by `json-schema-to-typescript`.
|
||||
*/
|
||||
function cleanJsDoc(content: string): string {
|
||||
const patterns = [
|
||||
/\* This interface was referenced by .+ JSON-Schema definition/,
|
||||
/\* via the `.+` "/,
|
||||
];
|
||||
|
||||
return content
|
||||
.split('\n')
|
||||
.filter(line => !patterns.some(ignoredLine => ignoredLine.test(line)))
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace some types that are generated by `json-schema-to-typescript`.
|
||||
*/
|
||||
export function patchTypes(content: string): string {
|
||||
const replacements: [RegExp, string][] = [
|
||||
[
|
||||
/\(string & \{\s*\[k: string\]: any\s*\} & \{\s*\[k: string\]: any\s*\}\)\[\]/,
|
||||
'string[]',
|
||||
],
|
||||
];
|
||||
|
||||
for (const [pattern, replacement] of replacements) {
|
||||
content = content.replace(pattern, replacement);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a type from the given JSON schema.
|
||||
*/
|
||||
export async function generateTypeFromSchema(
|
||||
schema: JSONSchema4,
|
||||
typeName: string,
|
||||
): Promise<string> {
|
||||
schema = JSON.parse(
|
||||
JSON.stringify(schema).replace(/#\/items\/0\/\$defs\//g, '#/$defs/'),
|
||||
);
|
||||
const result = await compile(schema, typeName, {
|
||||
format: false,
|
||||
bannerComment: '',
|
||||
style: {
|
||||
singleQuote: true,
|
||||
trailingComma: 'all',
|
||||
},
|
||||
unknownAny: false,
|
||||
});
|
||||
|
||||
return patchTypes(cleanJsDoc(result));
|
||||
}
|
145
packages/eslint-define-config/scripts/plugins-map.ts
Normal file
145
packages/eslint-define-config/scripts/plugins-map.ts
Normal file
@ -0,0 +1,145 @@
|
||||
import type { Plugin, PluginRules } from './utils';
|
||||
|
||||
/**
|
||||
* Map of plugins for which the script will generate rule files.
|
||||
*/
|
||||
export const PLUGIN_REGISTRY: Plugin[] = [
|
||||
{
|
||||
id: 'deprecation',
|
||||
name: 'Deprecation',
|
||||
module: () => import('eslint-plugin-deprecation'),
|
||||
},
|
||||
{
|
||||
id: 'eslint',
|
||||
name: 'ESLint',
|
||||
module: () => import('eslint'),
|
||||
},
|
||||
{
|
||||
id: 'typescript-eslint',
|
||||
name: 'TypeScript',
|
||||
prefix: '@typescript-eslint',
|
||||
module: () => import('@typescript-eslint/eslint-plugin'),
|
||||
},
|
||||
{
|
||||
id: 'import',
|
||||
name: 'Import',
|
||||
module: () => import('eslint-plugin-import'),
|
||||
},
|
||||
{
|
||||
id: 'eslint-comments',
|
||||
name: 'EslintComments',
|
||||
module: () => import('eslint-plugin-eslint-comments'),
|
||||
},
|
||||
{
|
||||
id: 'graphql-eslint',
|
||||
name: 'GraphQL',
|
||||
prefix: '@graphql-eslint',
|
||||
module: () => import('@graphql-eslint/eslint-plugin'),
|
||||
},
|
||||
{
|
||||
id: 'jsdoc',
|
||||
name: 'JSDoc',
|
||||
prefix: 'jsdoc',
|
||||
module: () => import('eslint-plugin-jsdoc'),
|
||||
},
|
||||
{
|
||||
id: 'jsonc',
|
||||
name: 'Jsonc',
|
||||
module: () => import('eslint-plugin-jsonc'),
|
||||
},
|
||||
{
|
||||
id: 'jsx-a11y',
|
||||
name: 'JsxA11y',
|
||||
module: () => import('eslint-plugin-jsx-a11y'),
|
||||
},
|
||||
{
|
||||
id: 'mdx',
|
||||
name: 'Mdx',
|
||||
module: () => import('eslint-plugin-mdx'),
|
||||
},
|
||||
{
|
||||
id: 'n',
|
||||
name: 'N',
|
||||
module: () => import('eslint-plugin-n'),
|
||||
},
|
||||
{
|
||||
id: 'node',
|
||||
name: 'Node',
|
||||
module: () => import('eslint-plugin-node'),
|
||||
},
|
||||
{
|
||||
id: 'promise',
|
||||
name: 'Promise',
|
||||
module: () => import('eslint-plugin-promise'),
|
||||
},
|
||||
{
|
||||
id: 'react',
|
||||
name: 'React',
|
||||
module: () => import('eslint-plugin-react'),
|
||||
},
|
||||
{
|
||||
id: 'react-hooks',
|
||||
name: 'ReactHooks',
|
||||
module: () => import('eslint-plugin-react-hooks'),
|
||||
},
|
||||
{
|
||||
id: 'sonarjs',
|
||||
name: 'SonarJS',
|
||||
prefix: 'sonarjs',
|
||||
module: () => import('eslint-plugin-sonarjs'),
|
||||
},
|
||||
{
|
||||
id: 'spellcheck',
|
||||
name: 'Spellcheck',
|
||||
module: () => import('eslint-plugin-spellcheck'),
|
||||
},
|
||||
{
|
||||
id: 'testing-library',
|
||||
name: 'TestingLibrary',
|
||||
module: () => import('eslint-plugin-testing-library'),
|
||||
},
|
||||
{
|
||||
id: 'unicorn',
|
||||
name: 'Unicorn',
|
||||
module: () => import('eslint-plugin-unicorn'),
|
||||
},
|
||||
{
|
||||
id: 'vitest',
|
||||
name: 'Vitest',
|
||||
module: () => import('eslint-plugin-vitest'),
|
||||
},
|
||||
{
|
||||
id: 'vue',
|
||||
name: 'Vue',
|
||||
module: () => import('eslint-plugin-vue'),
|
||||
},
|
||||
{
|
||||
id: 'vue-i18n',
|
||||
name: 'VueI18n',
|
||||
prefix: '@intlify/vue-i18n',
|
||||
module: () => import('@intlify/eslint-plugin-vue-i18n'),
|
||||
},
|
||||
{
|
||||
id: 'vue-pug',
|
||||
name: 'VuePug',
|
||||
module: () => import('eslint-plugin-vue-pug'),
|
||||
},
|
||||
{
|
||||
id: 'yml',
|
||||
name: 'Yml',
|
||||
module: () => import('eslint-plugin-yml'),
|
||||
},
|
||||
] as const;
|
||||
|
||||
export async function loadPlugin(plugin: Plugin): Promise<Plugin> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const mod: any = await plugin.module();
|
||||
const rules: PluginRules =
|
||||
plugin.name === 'ESLint'
|
||||
? Object.fromEntries(
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
new mod.Linter().getRules().entries(),
|
||||
)
|
||||
: mod.rules ?? mod.default.rules;
|
||||
return { ...plugin, rules };
|
||||
}
|
168
packages/eslint-define-config/scripts/rule-file.ts
Normal file
168
packages/eslint-define-config/scripts/rule-file.ts
Normal file
@ -0,0 +1,168 @@
|
||||
import { Logger, colors as cliColors } from '@poppinss/cliui';
|
||||
import { pascalCase, kebabCase } from 'change-case';
|
||||
import type { Rule } from 'eslint';
|
||||
import type { JSONSchema4 } from 'json-schema';
|
||||
import { execSync } from 'node:child_process';
|
||||
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import { format } from 'prettier';
|
||||
import { generateTypeFromSchema } from './json-schema-to-ts';
|
||||
import { buildJSDoc, prettierConfig, type Plugin } from './utils';
|
||||
|
||||
const logger = new Logger();
|
||||
const colors = cliColors.ansi();
|
||||
|
||||
/**
|
||||
* Build the rule description to append to the JSDoc.
|
||||
*/
|
||||
function buildDescription(description = ''): string {
|
||||
description = description.charAt(0).toUpperCase() + description.slice(1);
|
||||
if (description.length > 0 && !description.endsWith('.')) {
|
||||
description += '.';
|
||||
}
|
||||
|
||||
return description.replace('*/', '');
|
||||
}
|
||||
|
||||
export async function RuleFile(
|
||||
plugin: Plugin,
|
||||
pluginDirectory: string,
|
||||
ruleName: string,
|
||||
rule: Rule.RuleModule,
|
||||
) {
|
||||
let content = '';
|
||||
|
||||
const rulePath = resolve(pluginDirectory, `${ruleName}.d.ts`);
|
||||
const ruleNamePascalCase = pascalCase(ruleName);
|
||||
const schema: JSONSchema4 | JSONSchema4[] | undefined = rule.meta?.schema;
|
||||
const isSchemaArray = Array.isArray(schema);
|
||||
|
||||
const mainSchema = isSchemaArray ? schema[0] : schema;
|
||||
const sideSchema = isSchemaArray && schema.length > 1 ? schema[1] : undefined;
|
||||
const thirdSchema = isSchemaArray && schema.length > 2 ? schema[2] : undefined;
|
||||
|
||||
/**
|
||||
* Generate a JSDoc with the rule description and `@see` url.
|
||||
*/
|
||||
function generateTypeJsDoc(): string {
|
||||
const { meta } = rule;
|
||||
const seeDocLink: string = meta?.docs?.url
|
||||
? `@see [${ruleName}](${meta.docs.url})`
|
||||
: '';
|
||||
|
||||
return buildJSDoc([
|
||||
buildDescription(rule.meta?.docs?.description),
|
||||
' ',
|
||||
rule.meta?.deprecated ? '@deprecated' : '',
|
||||
rule.meta?.deprecated ? ' ' : '',
|
||||
seeDocLink,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a type from a JSON schema and append it to the file content.
|
||||
*/
|
||||
async function appendJsonSchemaType(
|
||||
schema: JSONSchema4,
|
||||
comment: string,
|
||||
): Promise<void> {
|
||||
const type = await generateTypeFromSchema(schema, ruleNamePascalCase + comment);
|
||||
const jsdoc = buildJSDoc([`${comment}.`]);
|
||||
content += `\n${jsdoc}`;
|
||||
content += `\n${type}\n`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scoped rule name ESLint config uses.
|
||||
*/
|
||||
function prefixedRuleName(): string {
|
||||
const { prefix, name } = plugin;
|
||||
const rulePrefix = (prefix ?? kebabCase(name)) + '/';
|
||||
return name === 'ESLint' ? ruleName : `${rulePrefix}${ruleName}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the `import type { RuleConfig } from '../rule-config'` at the top of the file.
|
||||
*/
|
||||
const nestedDepth = ruleName.split('/').length;
|
||||
content += `import type { RuleConfig } from '${'../'.repeat(nestedDepth)}rule-config'\n\n`;
|
||||
|
||||
/**
|
||||
* Generate and append types for the rule schemas.
|
||||
*/
|
||||
if (thirdSchema) {
|
||||
await appendJsonSchemaType(thirdSchema, 'Setting');
|
||||
}
|
||||
if (sideSchema) {
|
||||
await appendJsonSchemaType(sideSchema, 'Config');
|
||||
}
|
||||
if (mainSchema) {
|
||||
await appendJsonSchemaType(mainSchema, 'Option');
|
||||
}
|
||||
|
||||
if (mainSchema) {
|
||||
/**
|
||||
* Append the rule type options to the file content.
|
||||
*/
|
||||
let type: string = '';
|
||||
if (!isSchemaArray) {
|
||||
type = `${ruleNamePascalCase}Option`;
|
||||
} else if (thirdSchema) {
|
||||
type = `[${ruleNamePascalCase}Option?, ${ruleNamePascalCase}Config?, ${ruleNamePascalCase}Setting?]`;
|
||||
} else if (sideSchema) {
|
||||
type = `[${ruleNamePascalCase}Option?, ${ruleNamePascalCase}Config?]`;
|
||||
} else if (mainSchema) {
|
||||
type = `[${ruleNamePascalCase}Option?]`;
|
||||
}
|
||||
|
||||
content += buildJSDoc(['Options.']) + '\n';
|
||||
content += `export type ${ruleNamePascalCase}Options = ${type}\n\n`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the rule config type to the file content.
|
||||
*/
|
||||
content += generateTypeJsDoc() + '\n';
|
||||
content += `export type ${ruleNamePascalCase}RuleConfig = RuleConfig<${mainSchema ? `${ruleNamePascalCase}Options` : '[]'}>;\n\n`;
|
||||
|
||||
/**
|
||||
* Append the final rule interface to the file content.
|
||||
*/
|
||||
content += generateTypeJsDoc() + '\n';
|
||||
content += `export interface ${ruleNamePascalCase}Rule {`;
|
||||
content += `${generateTypeJsDoc()}\n`;
|
||||
content += `'${prefixedRuleName()}': ${ruleNamePascalCase}RuleConfig;`;
|
||||
content += '}';
|
||||
|
||||
content = await format(content, prettierConfig);
|
||||
|
||||
/**
|
||||
* Create the directory of the rule file if it doesn't exist.
|
||||
*/
|
||||
const subPath = dirname(rulePath);
|
||||
if (!existsSync(subPath)) {
|
||||
mkdirSync(subPath, { recursive: true });
|
||||
}
|
||||
|
||||
writeFileSync(rulePath, content);
|
||||
|
||||
/**
|
||||
* Apply a patch to the generated content if a diff file exists for it.
|
||||
*
|
||||
* Must be called after `generate()`.
|
||||
*/
|
||||
const pathParts = rulePath.split('/');
|
||||
const diffFile = resolve(
|
||||
__dirname,
|
||||
'./diffs/rules',
|
||||
pathParts.at(-2) ?? '',
|
||||
`${pathParts.at(-1) ?? ''}.diff`,
|
||||
);
|
||||
|
||||
if (existsSync(diffFile)) {
|
||||
logger.logUpdate(colors.yellow(` 🧹 Adjusting ${prefixedRuleName()}`));
|
||||
logger.logUpdatePersist();
|
||||
|
||||
execSync(`git apply ${diffFile}`);
|
||||
}
|
||||
}
|
24
packages/eslint-define-config/scripts/utils.ts
Normal file
24
packages/eslint-define-config/scripts/utils.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import type { Rule } from 'eslint';
|
||||
import type { Config } from 'prettier';
|
||||
|
||||
export function buildJSDoc(content: string[]) {
|
||||
return ['/**', ...content.filter(Boolean).map(line => ` * ${line}`), ' */'].join('\n');
|
||||
}
|
||||
|
||||
export const prettierConfig: Config = {
|
||||
plugins: ['prettier-plugin-organize-imports'],
|
||||
parser: 'typescript',
|
||||
singleQuote: true,
|
||||
trailingComma: 'all',
|
||||
};
|
||||
|
||||
export type MaybeArray<T> = T | T[];
|
||||
export type PluginRules = Record<string, Rule.RuleModule>;
|
||||
|
||||
export interface Plugin {
|
||||
id: string;
|
||||
name: string;
|
||||
prefix?: string;
|
||||
module: () => Promise<any>;
|
||||
rules?: PluginRules;
|
||||
}
|
Submodule packages/eslint-import-resolver-typescript updated: 7b6bfc3947...7a02ac08b5
Submodule packages/eslint-plugin-import updated: 6b95a02193...f77ceb679d
Submodule packages/eslint-plugin-jsx-a11y updated: fffb05b38c...0d5321a545
Submodule packages/eslint-plugin-n updated: 47cd9a6a0e...eb11b5b35a
Submodule packages/eslint-plugin-react updated: ecadb92609...4467db503e
@ -8,20 +8,22 @@
|
||||
/* eslint-disable no-for-of-loops/no-for-of-loops */
|
||||
import type { Rule, Scope } from 'eslint';
|
||||
import type {
|
||||
FunctionDeclaration,
|
||||
CallExpression,
|
||||
Expression,
|
||||
Super,
|
||||
Node,
|
||||
ArrayExpression,
|
||||
ArrowFunctionExpression,
|
||||
FunctionExpression,
|
||||
SpreadElement,
|
||||
Identifier,
|
||||
VariableDeclarator,
|
||||
MemberExpression,
|
||||
CallExpression,
|
||||
ChainExpression,
|
||||
Pattern,
|
||||
Expression,
|
||||
FunctionDeclaration,
|
||||
FunctionExpression,
|
||||
Identifier,
|
||||
MemberExpression,
|
||||
Node,
|
||||
OptionalMemberExpression,
|
||||
Pattern,
|
||||
SpreadElement,
|
||||
Super,
|
||||
TSAsExpression,
|
||||
VariableDeclarator,
|
||||
} from 'estree';
|
||||
import type { FromSchema } from 'json-schema-to-ts';
|
||||
import { __EXPERIMENTAL__ } from './index';
|
||||
@ -109,7 +111,7 @@ const rule: Rule.RuleModule = {
|
||||
*/
|
||||
function visitFunctionWithDependencies(
|
||||
node: ArrowFunctionExpression | FunctionExpression | FunctionDeclaration,
|
||||
declaredDependenciesNode: SpreadElement | Expression,
|
||||
declaredDependenciesNode: SpreadElement | Expression | undefined,
|
||||
reactiveHook: Super | Expression,
|
||||
reactiveHookName: string,
|
||||
isEffect: boolean,
|
||||
@ -128,7 +130,7 @@ const rule: Rule.RuleModule = {
|
||||
' }\n' +
|
||||
' fetchData();\n' +
|
||||
`}, [someId]); // Or [] if effect doesn't need props or state\n\n` +
|
||||
'Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching',
|
||||
'Learn more about data fetching with Hooks: https://react.dev/link/hooks-data-fetching',
|
||||
});
|
||||
}
|
||||
|
||||
@ -194,7 +196,7 @@ const rule: Rule.RuleModule = {
|
||||
if (init == null) {
|
||||
return false;
|
||||
}
|
||||
while (init.type === 'TSAsExpression') {
|
||||
while (init.type === 'TSAsExpression' || init.type === 'AsExpression') {
|
||||
init = init.expression;
|
||||
}
|
||||
// Detect primitive constants
|
||||
@ -620,7 +622,11 @@ const rule: Rule.RuleModule = {
|
||||
|
||||
const declaredDependencies: DeclaredDependency[] = [];
|
||||
const externalDependencies = new Set<string>();
|
||||
if (declaredDependenciesNode.type !== 'ArrayExpression') {
|
||||
const isArrayExpression = declaredDependenciesNode.type === 'ArrayExpression';
|
||||
const isTSAsArrayExpression =
|
||||
declaredDependenciesNode.type === 'TSAsExpression' &&
|
||||
declaredDependenciesNode.expression.type === 'ArrayExpression';
|
||||
if (!isArrayExpression && !isTSAsArrayExpression) {
|
||||
// If the declared dependencies are not an array expression then we
|
||||
// can't verify that the user provided the correct dependencies. Tell
|
||||
// the user this in an error.
|
||||
@ -633,7 +639,10 @@ const rule: Rule.RuleModule = {
|
||||
'dependencies.',
|
||||
});
|
||||
} else {
|
||||
declaredDependenciesNode.elements.forEach(declaredDependencyNode => {
|
||||
const arrayExpression = isTSAsArrayExpression
|
||||
? ((declaredDependenciesNode as TSAsExpression).expression as ArrayExpression)
|
||||
: (declaredDependenciesNode as ArrayExpression);
|
||||
arrayExpression.elements.forEach(declaredDependencyNode => {
|
||||
// Skip elided elements.
|
||||
if (declaredDependencyNode === null) {
|
||||
return;
|
||||
@ -1158,7 +1167,11 @@ const rule: Rule.RuleModule = {
|
||||
const reactiveHook = node.callee as Identifier | MemberExpression;
|
||||
const reactiveHookName = (getNodeWithoutReactNamespace(reactiveHook) as Identifier)
|
||||
.name;
|
||||
const declaredDependenciesNode = node.arguments[callbackIndex + 1];
|
||||
const maybeNode = node.arguments[callbackIndex + 1];
|
||||
const declaredDependenciesNode =
|
||||
maybeNode && !(maybeNode.type === 'Identifier' && maybeNode.name === 'undefined')
|
||||
? maybeNode
|
||||
: undefined;
|
||||
const isEffect = /Effect($|[^a-z])/g.test(reactiveHookName);
|
||||
|
||||
// Check whether a callback is supplied. If there is no callback supplied
|
||||
@ -1203,6 +1216,15 @@ const rule: Rule.RuleModule = {
|
||||
isEffect,
|
||||
);
|
||||
return; // Handled
|
||||
case 'TSAsExpression':
|
||||
visitFunctionWithDependencies(
|
||||
callback.expression,
|
||||
declaredDependenciesNode,
|
||||
reactiveHook,
|
||||
reactiveHookName,
|
||||
isEffect,
|
||||
);
|
||||
return; // Handled
|
||||
case 'Identifier':
|
||||
if (!declaredDependenciesNode) {
|
||||
// No deps, no problems.
|
||||
@ -1545,7 +1567,7 @@ function getConstructionExpressionType(node: Node) {
|
||||
}
|
||||
return null;
|
||||
case 'TypeCastExpression':
|
||||
return getConstructionExpressionType(node.expression);
|
||||
case 'AsExpression':
|
||||
case 'TSAsExpression':
|
||||
return getConstructionExpressionType(node.expression);
|
||||
}
|
||||
@ -1749,7 +1771,7 @@ function analyzePropertyChain(
|
||||
}
|
||||
}
|
||||
|
||||
function getNodeWithoutReactNamespace(node: Identifier | MemberExpression) {
|
||||
function getNodeWithoutReactNamespace(node: Expression | Super) {
|
||||
if (
|
||||
node.type === 'MemberExpression' &&
|
||||
node.object.type === 'Identifier' &&
|
||||
|
@ -24,10 +24,7 @@ import { __EXPERIMENTAL__ } from './index';
|
||||
*/
|
||||
|
||||
function isHookName(s: string) {
|
||||
if (__EXPERIMENTAL__) {
|
||||
return s === 'use' || /^use[A-Z0-9]/.test(s);
|
||||
}
|
||||
return /^use[A-Z0-9]/.test(s);
|
||||
return s === 'use' || /^use[A-Z0-9]/.test(s);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -59,7 +56,7 @@ function isComponentName(node: Node) {
|
||||
return node.type === 'Identifier' && /^[A-Z]/.test(node.name);
|
||||
}
|
||||
|
||||
function isReactFunction(node: Expression | Super, functionName: string) {
|
||||
function isReactFunction(node: Node, functionName: string) {
|
||||
return (
|
||||
(node as Identifier).name === functionName ||
|
||||
(node.type === 'MemberExpression' &&
|
||||
@ -115,10 +112,7 @@ function isUseEffectEventIdentifier(node: Node) {
|
||||
}
|
||||
|
||||
function isUseIdentifier(node: Node) {
|
||||
if (__EXPERIMENTAL__) {
|
||||
return node.type === 'Identifier' && node.name === 'use';
|
||||
}
|
||||
return false;
|
||||
return isReactFunction(node, 'use');
|
||||
}
|
||||
|
||||
const rule: Rule.RuleModule = {
|
||||
|
@ -3,8 +3,8 @@
|
||||
"version": 1,
|
||||
"sources": {
|
||||
"main": {
|
||||
"repository": "git@github.com:facebook/react.git",
|
||||
"commit": "899cb95f52cc83ab5ca1eb1e268c909d3f0961e7",
|
||||
"repository": "https://github.com/facebook/react",
|
||||
"commit": "0e0b69321a6fcfe8a3eaae3b1016beb110437b38",
|
||||
"branch": "main"
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
diff --git a/package.json b/package.json
|
||||
index 510ac18..569cdc0 100644
|
||||
index 98370b5..da6cd9b 100644
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -62,8 +62,7 @@
|
||||
@ -14,13 +14,14 @@ index 510ac18..569cdc0 100644
|
||||
"debug": "^4.3.4",
|
||||
diff --git a/tsconfig.json b/tsconfig.json
|
||||
deleted file mode 100644
|
||||
index 81e4c05..0000000
|
||||
index a303861..0000000
|
||||
--- a/tsconfig.json
|
||||
+++ /dev/null
|
||||
@@ -1,7 +0,0 @@
|
||||
@@ -1,8 +0,0 @@
|
||||
-{
|
||||
- "extends": "@1stg/tsconfig/node16",
|
||||
- "compilerOptions": {
|
||||
- "module": "Node16",
|
||||
- "outDir": "./lib"
|
||||
- },
|
||||
- "include": ["./src", "./shim.d.ts"]
|
||||
|
@ -26,10 +26,10 @@ index 883c03b7..0111d616 100644
|
||||
}
|
||||
diff --git a/.eslintrc b/.eslintrc
|
||||
deleted file mode 100644
|
||||
index 3c9c658f..00000000
|
||||
index 80e1014c..00000000
|
||||
--- a/.eslintrc
|
||||
+++ /dev/null
|
||||
@@ -1,248 +0,0 @@
|
||||
@@ -1,267 +0,0 @@
|
||||
-{
|
||||
- "root": true,
|
||||
- "plugins": [
|
||||
@ -128,6 +128,7 @@ index 3c9c658f..00000000
|
||||
- "no-multiple-empty-lines": [2, { "max": 1, "maxEOF": 1, "maxBOF": 0 }],
|
||||
- "no-return-assign": [2, "always"],
|
||||
- "no-trailing-spaces": 2,
|
||||
- "no-use-before-define": [2, { "functions": true, "classes": true, "variables": true }],
|
||||
- "no-var": 2,
|
||||
- "object-curly-spacing": [2, "always"],
|
||||
- "object-shorthand": ["error", "always", {
|
||||
@ -241,10 +242,10 @@ index 3c9c658f..00000000
|
||||
- "exports": "always-multiline",
|
||||
- "functions": "never"
|
||||
- }],
|
||||
- "prefer-destructuring": "warn",
|
||||
- "prefer-destructuring": "off",
|
||||
- "prefer-object-spread": "off",
|
||||
- "prefer-rest-params": "off",
|
||||
- "prefer-spread": "warn",
|
||||
- "prefer-spread": "off",
|
||||
- "prefer-template": "off",
|
||||
- }
|
||||
- },
|
||||
@ -259,6 +260,24 @@ index 3c9c658f..00000000
|
||||
- },
|
||||
- {
|
||||
- "files": [
|
||||
- "utils/**", // TODO
|
||||
- ],
|
||||
- "rules": {
|
||||
- "no-use-before-define": "off",
|
||||
- },
|
||||
- },
|
||||
- {
|
||||
- "files": [
|
||||
- "resolvers/webpack/index.js",
|
||||
- "resolvers/webpack/test/example.js",
|
||||
- "utils/parse.js",
|
||||
- ],
|
||||
- "rules": {
|
||||
- "no-console": "off",
|
||||
- },
|
||||
- },
|
||||
- {
|
||||
- "files": [
|
||||
- "resolvers/*/test/**/*",
|
||||
- ],
|
||||
- "env": {
|
||||
|
@ -1,5 +1,5 @@
|
||||
diff --git a/lib/index.js b/lib/index.js
|
||||
index def1bbf..6fdff14 100644
|
||||
index 49fd4c7..a0fdd81 100644
|
||||
--- a/lib/index.js
|
||||
+++ b/lib/index.js
|
||||
@@ -1,9 +1,9 @@
|
||||
@ -14,111 +14,16 @@ index def1bbf..6fdff14 100644
|
||||
+import cjsConfig from "./configs/recommended-script"
|
||||
+import recommendedConfig from "./configs/recommended"
|
||||
|
||||
const rules = {
|
||||
"callback-return": require("./rules/callback-return"),
|
||||
@@ -51,8 +51,8 @@ const rules = {
|
||||
|
||||
const mod = {
|
||||
/**
|
||||
* @typedef {{
|
||||
@@ -20,8 +20,8 @@ const recommendedConfig = require("./configs/recommended")
|
||||
/** @type {import('eslint').ESLint.Plugin & { configs: Configs }} */
|
||||
const plugin = {
|
||||
meta: {
|
||||
- name: pkg.name,
|
||||
- version: pkg.version,
|
||||
+ name,
|
||||
+ version,
|
||||
},
|
||||
rules,
|
||||
}
|
||||
diff --git a/tests/fixtures/no-extraneous/dependencies/node_modules/@bbb/aaa.js b/tests/fixtures/no-extraneous/dependencies/node_modules/@bbb/aaa.js
|
||||
deleted file mode 100644
|
||||
index e69de29..0000000
|
||||
diff --git a/tests/fixtures/no-extraneous/dependencies/node_modules/aaa.js b/tests/fixtures/no-extraneous/dependencies/node_modules/aaa.js
|
||||
deleted file mode 100644
|
||||
index e69de29..0000000
|
||||
diff --git a/tests/fixtures/no-extraneous/dependencies/node_modules/bbb/index.js b/tests/fixtures/no-extraneous/dependencies/node_modules/bbb/index.js
|
||||
deleted file mode 100644
|
||||
index e69de29..0000000
|
||||
diff --git a/tests/fixtures/no-extraneous/dependencies/node_modules/bbb/package.json b/tests/fixtures/no-extraneous/dependencies/node_modules/bbb/package.json
|
||||
deleted file mode 100644
|
||||
index b7d25e2..0000000
|
||||
--- a/tests/fixtures/no-extraneous/dependencies/node_modules/bbb/package.json
|
||||
+++ /dev/null
|
||||
@@ -1,4 +0,0 @@
|
||||
-{
|
||||
- "name": "bbb",
|
||||
- "main": "index.js"
|
||||
-}
|
||||
\ No newline at end of file
|
||||
diff --git a/tests/fixtures/no-extraneous/devDependencies/node_modules/@bbb/aaa.js b/tests/fixtures/no-extraneous/devDependencies/node_modules/@bbb/aaa.js
|
||||
deleted file mode 100644
|
||||
index e69de29..0000000
|
||||
diff --git a/tests/fixtures/no-extraneous/devDependencies/node_modules/aaa.js b/tests/fixtures/no-extraneous/devDependencies/node_modules/aaa.js
|
||||
deleted file mode 100644
|
||||
index e69de29..0000000
|
||||
diff --git a/tests/fixtures/no-extraneous/devDependencies/node_modules/bbb/index.js b/tests/fixtures/no-extraneous/devDependencies/node_modules/bbb/index.js
|
||||
deleted file mode 100644
|
||||
index e69de29..0000000
|
||||
diff --git a/tests/fixtures/no-extraneous/devDependencies/node_modules/bbb/package.json b/tests/fixtures/no-extraneous/devDependencies/node_modules/bbb/package.json
|
||||
deleted file mode 100644
|
||||
index b7d25e2..0000000
|
||||
--- a/tests/fixtures/no-extraneous/devDependencies/node_modules/bbb/package.json
|
||||
+++ /dev/null
|
||||
@@ -1,4 +0,0 @@
|
||||
-{
|
||||
- "name": "bbb",
|
||||
- "main": "index.js"
|
||||
-}
|
||||
\ No newline at end of file
|
||||
diff --git a/tests/fixtures/no-extraneous/noDependencies/node_modules/@bbb/aaa.js b/tests/fixtures/no-extraneous/noDependencies/node_modules/@bbb/aaa.js
|
||||
deleted file mode 100644
|
||||
index e69de29..0000000
|
||||
diff --git a/tests/fixtures/no-extraneous/noDependencies/node_modules/aaa.js b/tests/fixtures/no-extraneous/noDependencies/node_modules/aaa.js
|
||||
deleted file mode 100644
|
||||
index e69de29..0000000
|
||||
diff --git a/tests/fixtures/no-extraneous/noDependencies/node_modules/bbb.js b/tests/fixtures/no-extraneous/noDependencies/node_modules/bbb.js
|
||||
deleted file mode 100644
|
||||
index e69de29..0000000
|
||||
diff --git a/tests/fixtures/no-extraneous/optionalDependencies/node_modules/@bbb/aaa.js b/tests/fixtures/no-extraneous/optionalDependencies/node_modules/@bbb/aaa.js
|
||||
deleted file mode 100644
|
||||
index e69de29..0000000
|
||||
diff --git a/tests/fixtures/no-extraneous/optionalDependencies/node_modules/aaa.js b/tests/fixtures/no-extraneous/optionalDependencies/node_modules/aaa.js
|
||||
deleted file mode 100644
|
||||
index e69de29..0000000
|
||||
diff --git a/tests/fixtures/no-extraneous/optionalDependencies/node_modules/bbb/index.js b/tests/fixtures/no-extraneous/optionalDependencies/node_modules/bbb/index.js
|
||||
deleted file mode 100644
|
||||
index e69de29..0000000
|
||||
diff --git a/tests/fixtures/no-extraneous/optionalDependencies/node_modules/bbb/package.json b/tests/fixtures/no-extraneous/optionalDependencies/node_modules/bbb/package.json
|
||||
deleted file mode 100644
|
||||
index b7d25e2..0000000
|
||||
--- a/tests/fixtures/no-extraneous/optionalDependencies/node_modules/bbb/package.json
|
||||
+++ /dev/null
|
||||
@@ -1,4 +0,0 @@
|
||||
-{
|
||||
- "name": "bbb",
|
||||
- "main": "index.js"
|
||||
-}
|
||||
\ No newline at end of file
|
||||
diff --git a/tests/fixtures/no-extraneous/peerDependencies/node_modules/@bbb/aaa.js b/tests/fixtures/no-extraneous/peerDependencies/node_modules/@bbb/aaa.js
|
||||
deleted file mode 100644
|
||||
index e69de29..0000000
|
||||
diff --git a/tests/fixtures/no-extraneous/peerDependencies/node_modules/aaa.js b/tests/fixtures/no-extraneous/peerDependencies/node_modules/aaa.js
|
||||
deleted file mode 100644
|
||||
index e69de29..0000000
|
||||
diff --git a/tests/fixtures/no-extraneous/peerDependencies/node_modules/bbb/index.js b/tests/fixtures/no-extraneous/peerDependencies/node_modules/bbb/index.js
|
||||
deleted file mode 100644
|
||||
index e69de29..0000000
|
||||
diff --git a/tests/fixtures/no-extraneous/peerDependencies/node_modules/bbb/package.json b/tests/fixtures/no-extraneous/peerDependencies/node_modules/bbb/package.json
|
||||
deleted file mode 100644
|
||||
index b7d25e2..0000000
|
||||
--- a/tests/fixtures/no-extraneous/peerDependencies/node_modules/bbb/package.json
|
||||
+++ /dev/null
|
||||
@@ -1,4 +0,0 @@
|
||||
-{
|
||||
- "name": "bbb",
|
||||
- "main": "index.js"
|
||||
-}
|
||||
\ No newline at end of file
|
||||
diff --git a/tests/fixtures/no-hide-core-modules/indirect-thirdparty/node_modules/util/index.js b/tests/fixtures/no-hide-core-modules/indirect-thirdparty/node_modules/util/index.js
|
||||
deleted file mode 100644
|
||||
index e69de29..0000000
|
||||
diff --git a/tests/fixtures/no-hide-core-modules/thirdparty/node_modules/util/index.js b/tests/fixtures/no-hide-core-modules/thirdparty/node_modules/util/index.js
|
||||
deleted file mode 100644
|
||||
index e69de29..0000000
|
||||
rules: /** @type {Record<string, import('eslint').Rule.RuleModule>} */ ({
|
||||
"callback-return": require("./rules/callback-return"),
|
||||
|
@ -171,7 +171,7 @@ index 38b4dd8b..d0575572 100644
|
||||
const variableUtil = require('../util/variable');
|
||||
const testReactVersion = require('../util/version').testReactVersion;
|
||||
diff --git a/lib/rules/jsx-key.js b/lib/rules/jsx-key.js
|
||||
index c13a00cf..fb457e63 100644
|
||||
index 7ea874d0..48df0dba 100644
|
||||
--- a/lib/rules/jsx-key.js
|
||||
+++ b/lib/rules/jsx-key.js
|
||||
@@ -5,8 +5,7 @@
|
||||
@ -185,7 +185,7 @@ index c13a00cf..fb457e63 100644
|
||||
const docsUrl = require('../util/docsUrl');
|
||||
const pragmaUtil = require('../util/pragma');
|
||||
diff --git a/lib/rules/jsx-no-bind.js b/lib/rules/jsx-no-bind.js
|
||||
index 0a4c38e6..75a57bd9 100644
|
||||
index 17e56e2e..cb6dec1a 100644
|
||||
--- a/lib/rules/jsx-no-bind.js
|
||||
+++ b/lib/rules/jsx-no-bind.js
|
||||
@@ -7,7 +7,7 @@
|
||||
@ -198,7 +198,7 @@ index 0a4c38e6..75a57bd9 100644
|
||||
const jsxUtil = require('../util/jsx');
|
||||
const report = require('../util/report');
|
||||
diff --git a/lib/rules/jsx-pascal-case.js b/lib/rules/jsx-pascal-case.js
|
||||
index a1bb4811..db051356 100644
|
||||
index efeef403..33df4653 100644
|
||||
--- a/lib/rules/jsx-pascal-case.js
|
||||
+++ b/lib/rules/jsx-pascal-case.js
|
||||
@@ -5,7 +5,7 @@
|
||||
@ -211,7 +211,7 @@ index a1bb4811..db051356 100644
|
||||
const docsUrl = require('../util/docsUrl');
|
||||
const jsxUtil = require('../util/jsx');
|
||||
diff --git a/lib/rules/jsx-sort-props.js b/lib/rules/jsx-sort-props.js
|
||||
index 6d19f201..4b1849cc 100644
|
||||
index 3ca1724e..faf58f91 100644
|
||||
--- a/lib/rules/jsx-sort-props.js
|
||||
+++ b/lib/rules/jsx-sort-props.js
|
||||
@@ -5,7 +5,7 @@
|
||||
@ -224,7 +224,7 @@ index 6d19f201..4b1849cc 100644
|
||||
const toSorted = require('array.prototype.tosorted');
|
||||
|
||||
diff --git a/lib/rules/no-namespace.js b/lib/rules/no-namespace.js
|
||||
index 64bbc8d5..b5e9c803 100644
|
||||
index d7559f5e..fbfad23a 100644
|
||||
--- a/lib/rules/no-namespace.js
|
||||
+++ b/lib/rules/no-namespace.js
|
||||
@@ -5,7 +5,7 @@
|
||||
@ -237,10 +237,10 @@ index 64bbc8d5..b5e9c803 100644
|
||||
const isCreateElement = require('../util/isCreateElement');
|
||||
const report = require('../util/report');
|
||||
diff --git a/lib/rules/no-unknown-property.js b/lib/rules/no-unknown-property.js
|
||||
index 2fc127b1..64d093b8 100644
|
||||
index 9491f9c6..44396948 100644
|
||||
--- a/lib/rules/no-unknown-property.js
|
||||
+++ b/lib/rules/no-unknown-property.js
|
||||
@@ -540,7 +540,7 @@ module.exports = {
|
||||
@@ -543,7 +543,7 @@ module.exports = {
|
||||
|
||||
create(context) {
|
||||
function getIgnoreConfig() {
|
||||
@ -249,7 +249,7 @@ index 2fc127b1..64d093b8 100644
|
||||
}
|
||||
|
||||
function getRequireDataLowercase() {
|
||||
@@ -553,7 +553,7 @@ module.exports = {
|
||||
@@ -556,7 +556,7 @@ module.exports = {
|
||||
JSXAttribute(node) {
|
||||
const ignoreNames = getIgnoreConfig();
|
||||
const actualName = context.getSourceCode().getText(node.name);
|
||||
@ -258,22 +258,6 @@ index 2fc127b1..64d093b8 100644
|
||||
return;
|
||||
}
|
||||
const name = normalizeAttributeCase(actualName);
|
||||
@@ -581,6 +581,15 @@ module.exports = {
|
||||
|
||||
const tagName = getTagName(node);
|
||||
|
||||
+ if (
|
||||
+ (actualName === 'css' && hasEmotion) ||
|
||||
+ (tagName === 'style' &&
|
||||
+ (actualName === 'global' || actualName === 'jsx') &&
|
||||
+ hasNext)
|
||||
+ ) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (tagName === 'fbt' || tagName === 'fbs') { return; } // fbt/fbs nodes are bonkers, let's not go there
|
||||
|
||||
if (!isValidHTMLTagInJSX(node)) { return; }
|
||||
diff --git a/lib/util/annotations.js b/lib/util/annotations.js
|
||||
index 60aaef8c..ad8dc0bf 100644
|
||||
--- a/lib/util/annotations.js
|
||||
|
10
patches/@typescript-eslint+utils+6.13.1.patch
Normal file
10
patches/@typescript-eslint+utils+6.13.1.patch
Normal file
@ -0,0 +1,10 @@
|
||||
diff --git a/node_modules/@typescript-eslint/utils/dist/ts-eslint/Scope.d.ts b/node_modules/@typescript-eslint/utils/dist/ts-eslint/Scope.d.ts
|
||||
index 4e57af9..29b7cf7 100644
|
||||
--- a/node_modules/@typescript-eslint/utils/dist/ts-eslint/Scope.d.ts
|
||||
+++ b/node_modules/@typescript-eslint/utils/dist/ts-eslint/Scope.d.ts
|
||||
@@ -1,4 +1,4 @@
|
||||
-import * as scopeManager from '@typescript-eslint/scope-manager';
|
||||
+import * as scopeManager from '@typescript-eslint/scope-manager/dist';
|
||||
declare namespace Scope {
|
||||
type ScopeManager = scopeManager.ScopeManager;
|
||||
type Reference = scopeManager.Reference;
|
3
playground/.eslintrc.js
Normal file
3
playground/.eslintrc.js
Normal file
@ -0,0 +1,3 @@
|
||||
const { extendConfig } = require('@aet/eslint-rules');
|
||||
|
||||
module.exports = extendConfig({});
|
17
playground/package.json
Normal file
17
playground/package.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "playground",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@aet/eslint-rules": "link:/Users/aet/Documents/Git/eslint/dist",
|
||||
"eslint": "^8.54.0",
|
||||
"typescript": "^5.3.2"
|
||||
}
|
||||
}
|
672
playground/pnpm-lock.yaml
generated
Normal file
672
playground/pnpm-lock.yaml
generated
Normal file
@ -0,0 +1,672 @@
|
||||
lockfileVersion: '6.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
'@aet/eslint-rules':
|
||||
specifier: link:/Users/aet/Documents/Git/eslint/dist
|
||||
version: link:../dist
|
||||
eslint:
|
||||
specifier: 8.54.0
|
||||
version: 8.54.0
|
||||
typescript:
|
||||
specifier: ^5.3.2
|
||||
version: 5.3.2
|
||||
|
||||
packages:
|
||||
|
||||
/@aashutoshrathi/word-wrap@1.2.6:
|
||||
resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/@eslint-community/eslint-utils@4.4.0(eslint@8.54.0):
|
||||
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
|
||||
dependencies:
|
||||
eslint: 8.54.0
|
||||
eslint-visitor-keys: 3.4.3
|
||||
dev: false
|
||||
|
||||
/@eslint-community/regexpp@4.10.0:
|
||||
resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==}
|
||||
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
|
||||
dev: false
|
||||
|
||||
/@eslint/eslintrc@2.1.3:
|
||||
resolution: {integrity: sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dependencies:
|
||||
ajv: 6.12.6
|
||||
debug: 4.3.4
|
||||
espree: 9.6.1
|
||||
globals: 13.23.0
|
||||
ignore: 5.3.0
|
||||
import-fresh: 3.3.0
|
||||
js-yaml: 4.1.0
|
||||
minimatch: 3.1.2
|
||||
strip-json-comments: 3.1.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@eslint/js@8.54.0:
|
||||
resolution: {integrity: sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dev: false
|
||||
|
||||
/@humanwhocodes/config-array@0.11.13:
|
||||
resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==}
|
||||
engines: {node: '>=10.10.0'}
|
||||
dependencies:
|
||||
'@humanwhocodes/object-schema': 2.0.1
|
||||
debug: 4.3.4
|
||||
minimatch: 3.1.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@humanwhocodes/module-importer@1.0.1:
|
||||
resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
|
||||
engines: {node: '>=12.22'}
|
||||
dev: false
|
||||
|
||||
/@humanwhocodes/object-schema@2.0.1:
|
||||
resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==}
|
||||
dev: false
|
||||
|
||||
/@nodelib/fs.scandir@2.1.5:
|
||||
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
||||
engines: {node: '>= 8'}
|
||||
dependencies:
|
||||
'@nodelib/fs.stat': 2.0.5
|
||||
run-parallel: 1.2.0
|
||||
dev: false
|
||||
|
||||
/@nodelib/fs.stat@2.0.5:
|
||||
resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
|
||||
engines: {node: '>= 8'}
|
||||
dev: false
|
||||
|
||||
/@nodelib/fs.walk@1.2.8:
|
||||
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
|
||||
engines: {node: '>= 8'}
|
||||
dependencies:
|
||||
'@nodelib/fs.scandir': 2.1.5
|
||||
fastq: 1.15.0
|
||||
dev: false
|
||||
|
||||
/@ungap/structured-clone@1.2.0:
|
||||
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
|
||||
dev: false
|
||||
|
||||
/acorn-jsx@5.3.2(acorn@8.11.2):
|
||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||
peerDependencies:
|
||||
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||
dependencies:
|
||||
acorn: 8.11.2
|
||||
dev: false
|
||||
|
||||
/acorn@8.11.2:
|
||||
resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/ajv@6.12.6:
|
||||
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
fast-json-stable-stringify: 2.1.0
|
||||
json-schema-traverse: 0.4.1
|
||||
uri-js: 4.4.1
|
||||
dev: false
|
||||
|
||||
/ansi-regex@5.0.1:
|
||||
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/ansi-styles@4.3.0:
|
||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
dev: false
|
||||
|
||||
/argparse@2.0.1:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
dev: false
|
||||
|
||||
/balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
dev: false
|
||||
|
||||
/brace-expansion@1.1.11:
|
||||
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
concat-map: 0.0.1
|
||||
dev: false
|
||||
|
||||
/callsites@3.1.0:
|
||||
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/chalk@4.1.2:
|
||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
supports-color: 7.2.0
|
||||
dev: false
|
||||
|
||||
/color-convert@2.0.1:
|
||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||
engines: {node: '>=7.0.0'}
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
dev: false
|
||||
|
||||
/color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
dev: false
|
||||
|
||||
/concat-map@0.0.1:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
dev: false
|
||||
|
||||
/cross-spawn@7.0.3:
|
||||
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
||||
engines: {node: '>= 8'}
|
||||
dependencies:
|
||||
path-key: 3.1.1
|
||||
shebang-command: 2.0.0
|
||||
which: 2.0.2
|
||||
dev: false
|
||||
|
||||
/debug@4.3.4:
|
||||
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
dependencies:
|
||||
ms: 2.1.2
|
||||
dev: false
|
||||
|
||||
/deep-is@0.1.4:
|
||||
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
|
||||
dev: false
|
||||
|
||||
/doctrine@3.0.0:
|
||||
resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
dependencies:
|
||||
esutils: 2.0.3
|
||||
dev: false
|
||||
|
||||
/escape-string-regexp@4.0.0:
|
||||
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
|
||||
engines: {node: '>=10'}
|
||||
dev: false
|
||||
|
||||
/eslint-scope@7.2.2:
|
||||
resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dependencies:
|
||||
esrecurse: 4.3.0
|
||||
estraverse: 5.3.0
|
||||
dev: false
|
||||
|
||||
/eslint-visitor-keys@3.4.3:
|
||||
resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dev: false
|
||||
|
||||
/eslint@8.54.0:
|
||||
resolution: {integrity: sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0)
|
||||
'@eslint-community/regexpp': 4.10.0
|
||||
'@eslint/eslintrc': 2.1.3
|
||||
'@eslint/js': 8.54.0
|
||||
'@humanwhocodes/config-array': 0.11.13
|
||||
'@humanwhocodes/module-importer': 1.0.1
|
||||
'@nodelib/fs.walk': 1.2.8
|
||||
'@ungap/structured-clone': 1.2.0
|
||||
ajv: 6.12.6
|
||||
chalk: 4.1.2
|
||||
cross-spawn: 7.0.3
|
||||
debug: 4.3.4
|
||||
doctrine: 3.0.0
|
||||
escape-string-regexp: 4.0.0
|
||||
eslint-scope: 7.2.2
|
||||
eslint-visitor-keys: 3.4.3
|
||||
espree: 9.6.1
|
||||
esquery: 1.5.0
|
||||
esutils: 2.0.3
|
||||
fast-deep-equal: 3.1.3
|
||||
file-entry-cache: 6.0.1
|
||||
find-up: 5.0.0
|
||||
glob-parent: 6.0.2
|
||||
globals: 13.23.0
|
||||
graphemer: 1.4.0
|
||||
ignore: 5.3.0
|
||||
imurmurhash: 0.1.4
|
||||
is-glob: 4.0.3
|
||||
is-path-inside: 3.0.3
|
||||
js-yaml: 4.1.0
|
||||
json-stable-stringify-without-jsonify: 1.0.1
|
||||
levn: 0.4.1
|
||||
lodash.merge: 4.6.2
|
||||
minimatch: 3.1.2
|
||||
natural-compare: 1.4.0
|
||||
optionator: 0.9.3
|
||||
strip-ansi: 6.0.1
|
||||
text-table: 0.2.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/espree@9.6.1:
|
||||
resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dependencies:
|
||||
acorn: 8.11.2
|
||||
acorn-jsx: 5.3.2(acorn@8.11.2)
|
||||
eslint-visitor-keys: 3.4.3
|
||||
dev: false
|
||||
|
||||
/esquery@1.5.0:
|
||||
resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==}
|
||||
engines: {node: '>=0.10'}
|
||||
dependencies:
|
||||
estraverse: 5.3.0
|
||||
dev: false
|
||||
|
||||
/esrecurse@4.3.0:
|
||||
resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
|
||||
engines: {node: '>=4.0'}
|
||||
dependencies:
|
||||
estraverse: 5.3.0
|
||||
dev: false
|
||||
|
||||
/estraverse@5.3.0:
|
||||
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
|
||||
engines: {node: '>=4.0'}
|
||||
dev: false
|
||||
|
||||
/esutils@2.0.3:
|
||||
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/fast-deep-equal@3.1.3:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
dev: false
|
||||
|
||||
/fast-json-stable-stringify@2.1.0:
|
||||
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
|
||||
dev: false
|
||||
|
||||
/fast-levenshtein@2.0.6:
|
||||
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
|
||||
dev: false
|
||||
|
||||
/fastq@1.15.0:
|
||||
resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
|
||||
dependencies:
|
||||
reusify: 1.0.4
|
||||
dev: false
|
||||
|
||||
/file-entry-cache@6.0.1:
|
||||
resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
|
||||
engines: {node: ^10.12.0 || >=12.0.0}
|
||||
dependencies:
|
||||
flat-cache: 3.2.0
|
||||
dev: false
|
||||
|
||||
/find-up@5.0.0:
|
||||
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
locate-path: 6.0.0
|
||||
path-exists: 4.0.0
|
||||
dev: false
|
||||
|
||||
/flat-cache@3.2.0:
|
||||
resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==}
|
||||
engines: {node: ^10.12.0 || >=12.0.0}
|
||||
dependencies:
|
||||
flatted: 3.2.9
|
||||
keyv: 4.5.4
|
||||
rimraf: 3.0.2
|
||||
dev: false
|
||||
|
||||
/flatted@3.2.9:
|
||||
resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
|
||||
dev: false
|
||||
|
||||
/fs.realpath@1.0.0:
|
||||
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
||||
dev: false
|
||||
|
||||
/glob-parent@6.0.2:
|
||||
resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
dependencies:
|
||||
is-glob: 4.0.3
|
||||
dev: false
|
||||
|
||||
/glob@7.2.3:
|
||||
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
|
||||
dependencies:
|
||||
fs.realpath: 1.0.0
|
||||
inflight: 1.0.6
|
||||
inherits: 2.0.4
|
||||
minimatch: 3.1.2
|
||||
once: 1.4.0
|
||||
path-is-absolute: 1.0.1
|
||||
dev: false
|
||||
|
||||
/globals@13.23.0:
|
||||
resolution: {integrity: sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
type-fest: 0.20.2
|
||||
dev: false
|
||||
|
||||
/graphemer@1.4.0:
|
||||
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
|
||||
dev: false
|
||||
|
||||
/has-flag@4.0.0:
|
||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/ignore@5.3.0:
|
||||
resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==}
|
||||
engines: {node: '>= 4'}
|
||||
dev: false
|
||||
|
||||
/import-fresh@3.3.0:
|
||||
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
parent-module: 1.0.1
|
||||
resolve-from: 4.0.0
|
||||
dev: false
|
||||
|
||||
/imurmurhash@0.1.4:
|
||||
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
|
||||
engines: {node: '>=0.8.19'}
|
||||
dev: false
|
||||
|
||||
/inflight@1.0.6:
|
||||
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
|
||||
dependencies:
|
||||
once: 1.4.0
|
||||
wrappy: 1.0.2
|
||||
dev: false
|
||||
|
||||
/inherits@2.0.4:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
dev: false
|
||||
|
||||
/is-extglob@2.1.1:
|
||||
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/is-glob@4.0.3:
|
||||
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dependencies:
|
||||
is-extglob: 2.1.1
|
||||
dev: false
|
||||
|
||||
/is-path-inside@3.0.3:
|
||||
resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/isexe@2.0.0:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
dev: false
|
||||
|
||||
/js-yaml@4.1.0:
|
||||
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
dev: false
|
||||
|
||||
/json-buffer@3.0.1:
|
||||
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
|
||||
dev: false
|
||||
|
||||
/json-schema-traverse@0.4.1:
|
||||
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
|
||||
dev: false
|
||||
|
||||
/json-stable-stringify-without-jsonify@1.0.1:
|
||||
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
|
||||
dev: false
|
||||
|
||||
/keyv@4.5.4:
|
||||
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
|
||||
dependencies:
|
||||
json-buffer: 3.0.1
|
||||
dev: false
|
||||
|
||||
/levn@0.4.1:
|
||||
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
dependencies:
|
||||
prelude-ls: 1.2.1
|
||||
type-check: 0.4.0
|
||||
dev: false
|
||||
|
||||
/locate-path@6.0.0:
|
||||
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
p-locate: 5.0.0
|
||||
dev: false
|
||||
|
||||
/lodash.merge@4.6.2:
|
||||
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
||||
dev: false
|
||||
|
||||
/minimatch@3.1.2:
|
||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
||||
dependencies:
|
||||
brace-expansion: 1.1.11
|
||||
dev: false
|
||||
|
||||
/ms@2.1.2:
|
||||
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
|
||||
dev: false
|
||||
|
||||
/natural-compare@1.4.0:
|
||||
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
||||
dev: false
|
||||
|
||||
/once@1.4.0:
|
||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||
dependencies:
|
||||
wrappy: 1.0.2
|
||||
dev: false
|
||||
|
||||
/optionator@0.9.3:
|
||||
resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
dependencies:
|
||||
'@aashutoshrathi/word-wrap': 1.2.6
|
||||
deep-is: 0.1.4
|
||||
fast-levenshtein: 2.0.6
|
||||
levn: 0.4.1
|
||||
prelude-ls: 1.2.1
|
||||
type-check: 0.4.0
|
||||
dev: false
|
||||
|
||||
/p-limit@3.1.0:
|
||||
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
yocto-queue: 0.1.0
|
||||
dev: false
|
||||
|
||||
/p-locate@5.0.0:
|
||||
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
p-limit: 3.1.0
|
||||
dev: false
|
||||
|
||||
/parent-module@1.0.1:
|
||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
callsites: 3.1.0
|
||||
dev: false
|
||||
|
||||
/path-exists@4.0.0:
|
||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/path-is-absolute@1.0.1:
|
||||
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/path-key@3.1.1:
|
||||
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/prelude-ls@1.2.1:
|
||||
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
dev: false
|
||||
|
||||
/punycode@2.3.1:
|
||||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/queue-microtask@1.2.3:
|
||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||
dev: false
|
||||
|
||||
/resolve-from@4.0.0:
|
||||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
||||
engines: {node: '>=4'}
|
||||
dev: false
|
||||
|
||||
/reusify@1.0.4:
|
||||
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
|
||||
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/rimraf@3.0.2:
|
||||
resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
glob: 7.2.3
|
||||
dev: false
|
||||
|
||||
/run-parallel@1.2.0:
|
||||
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
||||
dependencies:
|
||||
queue-microtask: 1.2.3
|
||||
dev: false
|
||||
|
||||
/shebang-command@2.0.0:
|
||||
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
shebang-regex: 3.0.0
|
||||
dev: false
|
||||
|
||||
/shebang-regex@3.0.0:
|
||||
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/strip-ansi@6.0.1:
|
||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
ansi-regex: 5.0.1
|
||||
dev: false
|
||||
|
||||
/strip-json-comments@3.1.1:
|
||||
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/supports-color@7.2.0:
|
||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
dev: false
|
||||
|
||||
/text-table@0.2.0:
|
||||
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
|
||||
dev: false
|
||||
|
||||
/type-check@0.4.0:
|
||||
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
dependencies:
|
||||
prelude-ls: 1.2.1
|
||||
dev: false
|
||||
|
||||
/type-fest@0.20.2:
|
||||
resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
|
||||
engines: {node: '>=10'}
|
||||
dev: false
|
||||
|
||||
/typescript@5.3.2:
|
||||
resolution: {integrity: sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/uri-js@4.4.1:
|
||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||
dependencies:
|
||||
punycode: 2.3.1
|
||||
dev: false
|
||||
|
||||
/which@2.0.2:
|
||||
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||
engines: {node: '>= 8'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
isexe: 2.0.0
|
||||
dev: false
|
||||
|
||||
/wrappy@1.0.2:
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
dev: false
|
||||
|
||||
/yocto-queue@0.1.0:
|
||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
engines: {node: '>=10'}
|
||||
dev: false
|
2059
pnpm-lock.yaml
generated
2059
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
153
scripts/build-all.ts
Executable file
153
scripts/build-all.ts
Executable file
@ -0,0 +1,153 @@
|
||||
#!/usr/bin/env bun
|
||||
import './build-local-rules';
|
||||
import { promises as fs } from 'node:fs';
|
||||
import { resolve, relative } from 'node:path';
|
||||
import { isBuiltin } from 'node:module';
|
||||
import esbuild from 'esbuild';
|
||||
import type { Plugin } from 'esbuild';
|
||||
import { memoize } from 'lodash';
|
||||
import { gray, green } from 'picocolors';
|
||||
import { dependencies } from '../dist/package.json';
|
||||
import { dts } from './dts';
|
||||
import { babelPlugin } from './modifier';
|
||||
|
||||
const ENV = (process.env.NODE_ENV ??= 'production');
|
||||
const PROD = ENV === 'production';
|
||||
|
||||
declare global {
|
||||
interface Array<T> {
|
||||
filter(
|
||||
predicate: BooleanConstructor,
|
||||
): Exclude<T, null | undefined | false | '' | 0>[];
|
||||
}
|
||||
}
|
||||
|
||||
const log = memoize(console.log);
|
||||
|
||||
const plugins: Plugin[] = [
|
||||
babelPlugin,
|
||||
{
|
||||
name: 'alias',
|
||||
setup(build) {
|
||||
build.onResolve({ filter: /^jsx-ast-utils$/ }, () => ({
|
||||
path: resolve('./packages/jsx-ast-utils/src/index.js'),
|
||||
}));
|
||||
build.onResolve({ filter: /^jsx-ast-utils\/.+$/ }, ({ path }) => ({
|
||||
path:
|
||||
resolve('./packages/jsx-ast-utils/', path.slice('jsx-ast-utils/'.length)) +
|
||||
'.js',
|
||||
}));
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
if (process.env.DEBUG) {
|
||||
plugins.push({
|
||||
name: 'deps-check',
|
||||
setup(build) {
|
||||
const declared = new Set(Object.keys(dependencies));
|
||||
|
||||
build.onResolve({ filter: /^.*$/ }, ({ path, importer }) => {
|
||||
if (
|
||||
!path.startsWith('./') &&
|
||||
!path.startsWith('../') &&
|
||||
!isBuiltin(path) &&
|
||||
path !== 'eslint' &&
|
||||
!path.startsWith('eslint/') &&
|
||||
!path.startsWith('eslint-module-utils/') &&
|
||||
!declared.has(path)
|
||||
) {
|
||||
log(green(path), gray('from'), './' + relative(process.cwd(), importer));
|
||||
}
|
||||
return null;
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function bundle(
|
||||
entry: string,
|
||||
outfile = entry
|
||||
.replace('./packages/', './dist/')
|
||||
.replace('src/', '')
|
||||
.replace('.ts', '.js'),
|
||||
) {
|
||||
return esbuild.build({
|
||||
entryPoints: [entry],
|
||||
outfile,
|
||||
bundle: true,
|
||||
minify: PROD,
|
||||
platform: 'node',
|
||||
packages: 'external',
|
||||
sourcemap: 'linked',
|
||||
plugins,
|
||||
define: {},
|
||||
alias: {},
|
||||
external: ['find-cache-dir'],
|
||||
banner: {
|
||||
js: '/* eslint-disable */',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function editPackageJson() {
|
||||
const [state, setState] = await useText('./dist/package.json');
|
||||
const distPackageJson = JSON.parse(state);
|
||||
|
||||
const overrideList = await fs.readdir('dist/overrides');
|
||||
const npmOverrides = Object.fromEntries(
|
||||
overrideList.map(name => [name, `file:./overrides/${name}`]),
|
||||
);
|
||||
Object.assign(distPackageJson, {
|
||||
overrides: npmOverrides,
|
||||
resolutions: Object.fromEntries(
|
||||
overrideList.map(name => [`**/${name}`, `file:./overrides/${name}`]),
|
||||
),
|
||||
pnpm: { overrides: npmOverrides },
|
||||
});
|
||||
|
||||
await setState(JSON.stringify(distPackageJson, null, 2) + '\n');
|
||||
}
|
||||
|
||||
async function useText(path: string) {
|
||||
const state = await fs.readFile(path, 'utf-8');
|
||||
const setState = (text: string) => fs.writeFile(path, text);
|
||||
return [state, setState] as const;
|
||||
}
|
||||
|
||||
function bundleType(source: string, output: string) {
|
||||
return dts({
|
||||
source,
|
||||
dist: output,
|
||||
project: './tsconfig.build.json',
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log('Building type definitions...');
|
||||
bundleType('./src/index.ts', './dist/index.d.ts');
|
||||
bundleType('./src/prettier.ts', './dist/prettier.d.ts');
|
||||
bundleType('./src/types.ts', './dist/types.d.ts');
|
||||
|
||||
console.log('Building packages...');
|
||||
await Promise.all([
|
||||
bundle('./packages/eslint-plugin-react/index.js'),
|
||||
bundle('./packages/eslint-plugin-import/src/index.js'),
|
||||
bundle('./packages/eslint-plugin-jsx-a11y/src/index.js'),
|
||||
bundle('./packages/eslint-plugin-react-hooks/index.ts'),
|
||||
bundle('./packages/eslint-plugin-n/lib/index.js', './dist/eslint-plugin-n/index.js'),
|
||||
bundle('./packages/eslint-import-resolver-typescript/src/index.ts'),
|
||||
bundle('./src/rules/index.ts', './dist/eslint-plugin-rules/index.js'),
|
||||
bundle('./src/local/index.ts', './dist/eslint-plugin-local/index.js'),
|
||||
bundle('./src/index.ts', './dist/index.js'),
|
||||
bundle('./src/types.ts', './dist/types.js'),
|
||||
bundle('./src/prettier.ts', './dist/prettier.js'),
|
||||
editPackageJson(),
|
||||
]);
|
||||
|
||||
console.log('Removing redirect...');
|
||||
const [distIndex, setDistIndex] = await useText('./dist/index.js');
|
||||
await setDistIndex(distIndex.replace(/import.*redirect.*;/g, ''));
|
||||
}
|
||||
|
||||
void main();
|
@ -1,8 +1,7 @@
|
||||
#!/usr/bin/env tsx
|
||||
import { readdirSync, writeFileSync } from 'node:fs';
|
||||
import { promises as fs } from 'node:fs';
|
||||
import { camelCase } from 'lodash';
|
||||
|
||||
const files = readdirSync('./src/rules')
|
||||
const files = (await fs.readdir('./src/rules'))
|
||||
.filter(file => file.endsWith('.ts'))
|
||||
.filter(file => file !== 'index.ts')
|
||||
.map(file => file.slice(0, -3));
|
||||
@ -21,4 +20,5 @@ export const rules: Record<
|
||||
};
|
||||
`.trim();
|
||||
|
||||
writeFileSync('./src/rules/index.ts', entryFile + '\n');
|
||||
console.log('Building local rules...');
|
||||
await fs.writeFile('./src/rules/index.ts', entryFile + '\n');
|
69
scripts/check-imports.ts
Executable file
69
scripts/check-imports.ts
Executable file
@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env bun
|
||||
import glob from 'fast-glob';
|
||||
import fs from 'fs';
|
||||
import { builtinModules } from 'module';
|
||||
import { uniq } from 'lodash';
|
||||
import { dependencies, peerDependencies, overrides } from '../dist/package.json';
|
||||
|
||||
function checkImports() {
|
||||
const deps = Object.keys({ ...dependencies, ...peerDependencies, ...overrides }).concat(
|
||||
'eslint',
|
||||
);
|
||||
const builtIn = new Set(builtinModules.flatMap(module => [module, `node:${module}`]));
|
||||
|
||||
function findRequires(text: string) {
|
||||
const list = Array.from(text.matchAll(/require\(["']([^"']+)["']\)/g))
|
||||
.map(m => m[1])
|
||||
.filter(
|
||||
module =>
|
||||
!(
|
||||
builtIn.has(module) ||
|
||||
module.startsWith('eslint/') ||
|
||||
module.startsWith('typescript/')
|
||||
),
|
||||
);
|
||||
return uniq(list);
|
||||
}
|
||||
|
||||
const moduleMap = glob
|
||||
.sync(['dist/**/*.js', '!dist/node_modules/**'])
|
||||
.map(path => ({ key: path, value: findRequires(fs.readFileSync(path, 'utf8')) }));
|
||||
|
||||
const files = Object.fromEntries(
|
||||
moduleMap
|
||||
.map(({ key, value }) => ({
|
||||
key,
|
||||
value: value.filter(
|
||||
module =>
|
||||
!(deps.includes(module) || deps.some(dep => module.startsWith(`${dep}/`))),
|
||||
),
|
||||
}))
|
||||
.filter(({ value }) => value.length > 0)
|
||||
.map(({ key, value }) => [key, value]),
|
||||
);
|
||||
const uselessDeps = Object.keys(dependencies).filter(
|
||||
dep => !moduleMap.some(({ value }) => value.includes(dep)),
|
||||
);
|
||||
|
||||
return {
|
||||
missingImports: files,
|
||||
unusedDependencies: uselessDeps,
|
||||
};
|
||||
}
|
||||
|
||||
function checkDeps() {
|
||||
const pkgJson = glob
|
||||
.sync(['dist/node_modules/@*/*/package.json', 'dist/node_modules/*/package.json'])
|
||||
.sort()
|
||||
.map(path => fs.readFileSync(path, 'utf8'))
|
||||
.map(content => JSON.parse(content))
|
||||
.filter(({ author }) => JSON.stringify(author ?? 'null').includes('ljharb'))
|
||||
.map(({ name }) => name);
|
||||
|
||||
return { suspiciousPackages: pkgJson };
|
||||
}
|
||||
|
||||
console.log({
|
||||
...checkImports(),
|
||||
...checkDeps(),
|
||||
});
|
39
scripts/dts.ts
Normal file
39
scripts/dts.ts
Normal file
@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env node
|
||||
import * as ts from 'typescript';
|
||||
import {
|
||||
generateDtsBundle,
|
||||
type EntryPointConfig,
|
||||
} from 'dts-bundle-generator/dist/bundle-generator';
|
||||
|
||||
export function dts({
|
||||
source,
|
||||
dist,
|
||||
project,
|
||||
}: {
|
||||
source: string;
|
||||
dist: string;
|
||||
project: string;
|
||||
}): void {
|
||||
const entry: EntryPointConfig = {
|
||||
filePath: source,
|
||||
failOnClass: false,
|
||||
libraries: {
|
||||
importedLibraries: ['eslint-define-config'],
|
||||
},
|
||||
output: {
|
||||
inlineDeclareExternals: false,
|
||||
inlineDeclareGlobals: false,
|
||||
sortNodes: false,
|
||||
noBanner: false,
|
||||
respectPreserveConstEnum: false,
|
||||
exportReferencedTypes: true,
|
||||
},
|
||||
};
|
||||
|
||||
const generatedDts = generateDtsBundle([entry], {
|
||||
preferredConfigPath: project,
|
||||
followSymlinks: false,
|
||||
});
|
||||
|
||||
ts.sys.writeFile(dist, generatedDts[0]);
|
||||
}
|
114
esbuild.ts → scripts/modifier.ts
Executable file → Normal file
114
esbuild.ts → scripts/modifier.ts
Executable file → Normal file
@ -1,22 +1,16 @@
|
||||
#!/usr/bin/env tsx
|
||||
import assert from 'node:assert';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { resolve, extname, relative } from 'node:path';
|
||||
import { isBuiltin } from 'node:module';
|
||||
import esbuild from 'esbuild';
|
||||
import { resolve, extname } from 'node:path';
|
||||
import type { Loader, Plugin } from 'esbuild';
|
||||
import * as babel from '@babel/core';
|
||||
import { memoize } from 'lodash';
|
||||
import { gray, green } from 'picocolors';
|
||||
import type { types as t, types } from '@babel/core';
|
||||
import { dependencies } from './dist/package.json';
|
||||
import { createMacro, type MacroHandler } from 'babel-plugin-macros';
|
||||
import * as polyfill from './src/polyfill';
|
||||
import * as polyfill from '../src/polyfill';
|
||||
|
||||
const polyfills = Object.keys(polyfill);
|
||||
|
||||
const ENV = process.env.NODE_ENV || 'development';
|
||||
const PROD = ENV === 'production';
|
||||
const ENV = (process.env.NODE_ENV ??= 'production');
|
||||
|
||||
class HandlerMap {
|
||||
map = new Map<string, MacroHandler>();
|
||||
@ -84,10 +78,22 @@ const map = new HandlerMap()
|
||||
'array.prototype.tosorted',
|
||||
proto(t => t.identifier('toSorted')),
|
||||
)
|
||||
.set(
|
||||
'array.prototype.toreversed',
|
||||
proto(t => t.identifier('toReversed')),
|
||||
)
|
||||
.set(
|
||||
'array.prototype.findlast',
|
||||
proto(t => t.identifier('findLast')),
|
||||
)
|
||||
.set(
|
||||
'string.prototype.matchall',
|
||||
proto(t => t.identifier('matchAll')),
|
||||
)
|
||||
.set(
|
||||
'string.prototype.includes',
|
||||
proto(t => t.identifier('includes')),
|
||||
)
|
||||
.set(
|
||||
'object.groupby',
|
||||
replace(t =>
|
||||
@ -99,7 +105,7 @@ const map = new HandlerMap()
|
||||
);
|
||||
|
||||
// es-iterator-helpers/Iterator.prototype.*
|
||||
const polyfillPath = resolve(__dirname, './src/polyfill.ts');
|
||||
const polyfillPath = resolve(__dirname, '../src/polyfill.ts');
|
||||
const requirePolyfill = (t: typeof types, name: string) =>
|
||||
t.memberExpression(
|
||||
t.callExpression(t.identifier('require'), [t.stringLiteral(polyfillPath)]),
|
||||
@ -116,6 +122,11 @@ for (const name of polyfills) {
|
||||
);
|
||||
}
|
||||
|
||||
map.set(
|
||||
'safe-regex-test',
|
||||
replace(t => requirePolyfill(t, 'safeRegexTest')),
|
||||
);
|
||||
|
||||
function replace(getReplacement: (types: typeof t) => t.Expression): MacroHandler {
|
||||
return ({ references, babel: { types: t } }) => {
|
||||
references.default.forEach(referencePath => {
|
||||
@ -193,86 +204,3 @@ export const babelPlugin: Plugin = {
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
declare global {
|
||||
interface Array<T> {
|
||||
filter(
|
||||
predicate: BooleanConstructor,
|
||||
): Exclude<T, null | undefined | false | '' | 0>[];
|
||||
}
|
||||
}
|
||||
|
||||
const log = memoize(console.log);
|
||||
|
||||
const plugins: Plugin[] = [
|
||||
babelPlugin,
|
||||
{
|
||||
name: 'alias',
|
||||
setup(build) {
|
||||
build.onResolve({ filter: /^jsx-ast-utils$/ }, () => ({
|
||||
path: resolve('./packages/jsx-ast-utils/src/index.js'),
|
||||
}));
|
||||
build.onResolve({ filter: /^jsx-ast-utils\/.+$/ }, ({ path }) => ({
|
||||
path:
|
||||
resolve('./packages/jsx-ast-utils/', path.slice('jsx-ast-utils/'.length)) +
|
||||
'.js',
|
||||
}));
|
||||
},
|
||||
},
|
||||
];
|
||||
if (process.env.DEBUG) {
|
||||
plugins.push({
|
||||
name: 'deps-check',
|
||||
setup(build) {
|
||||
const declared = new Set(Object.keys(dependencies));
|
||||
|
||||
build.onResolve({ filter: /^.*$/ }, ({ path, importer }) => {
|
||||
if (
|
||||
!path.startsWith('./') &&
|
||||
!path.startsWith('../') &&
|
||||
!isBuiltin(path) &&
|
||||
path !== 'eslint' &&
|
||||
!path.startsWith('eslint/') &&
|
||||
!path.startsWith('eslint-module-utils/') &&
|
||||
!declared.has(path)
|
||||
) {
|
||||
log(green(path), gray('from'), './' + relative(process.cwd(), importer));
|
||||
}
|
||||
return null;
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function main(
|
||||
entry: string,
|
||||
outfile = entry
|
||||
.replace('./packages/', './dist/')
|
||||
.replace('src/', '')
|
||||
.replace('.ts', '.js'),
|
||||
) {
|
||||
await esbuild.build({
|
||||
entryPoints: [entry],
|
||||
outfile,
|
||||
bundle: true,
|
||||
minify: PROD,
|
||||
platform: 'node',
|
||||
packages: 'external',
|
||||
sourcemap: 'linked',
|
||||
plugins,
|
||||
define: {},
|
||||
banner: {
|
||||
js: '/* eslint-disable */',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
main('./packages/eslint-plugin-react/index.js');
|
||||
main('./packages/eslint-plugin-import/src/index.js');
|
||||
main('./packages/eslint-plugin-jsx-a11y/src/index.js');
|
||||
main('./packages/eslint-plugin-react-hooks/index.ts');
|
||||
main('./packages/eslint-plugin-n/lib/index.js', './dist/eslint-plugin-n/index.js');
|
||||
main('./packages/eslint-import-resolver-typescript/src/index.ts');
|
||||
main('./src/rules/index.ts', './dist/eslint-plugin-rules/index.js');
|
||||
main('./src/local/index.ts', './dist/eslint-plugin-local/index.js');
|
||||
main('./src/index.ts', './dist/index.js');
|
@ -1,13 +1,22 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
git-pull() {
|
||||
name=$1
|
||||
git config pull.rebase true
|
||||
git config rebase.autoStash true
|
||||
git pull --quiet
|
||||
ref=$(git log -1 --pretty='{"hash":"%H","date":"%aI","committer":"%cn","subject":"%s"}')
|
||||
yq -iP ".$name=$ref" ../../src/commits.json -o json
|
||||
}
|
||||
|
||||
pull() {
|
||||
echo "🚛 Pulling $2"
|
||||
if [ ! -d "packages/$2" ]; then
|
||||
echo "📦 Repository not found, cloning..."
|
||||
git clone "https://github.com/$1/$2.git" "packages/$2"
|
||||
fi
|
||||
(cd "packages/$2" && git config pull.rebase true && git config rebase.autoStash true && git pull)
|
||||
(cd "packages/$2" && git-pull "$2")
|
||||
echo
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
#!/usr/bin/env bun
|
||||
import glob from 'fast-glob';
|
||||
import fs from 'fs';
|
||||
import { builtinModules } from 'module';
|
||||
import { uniq } from 'lodash';
|
||||
import { dependencies, peerDependencies } from '../dist/package.json';
|
||||
|
||||
const deps = Object.keys({ ...dependencies, ...peerDependencies }).concat('eslint');
|
||||
const builtIn = new Set(builtinModules.flatMap(module => [module, `node:${module}`]));
|
||||
|
||||
const files = Object.fromEntries(
|
||||
glob
|
||||
.sync('dist/**/*.js')
|
||||
.map(path => [
|
||||
path,
|
||||
uniq(
|
||||
Array.from(fs.readFileSync(path, 'utf8').matchAll(/require\(["']([^"']+)["']\)/g))
|
||||
.map(m => m[1])
|
||||
.filter(
|
||||
module =>
|
||||
!(
|
||||
builtIn.has(module) ||
|
||||
deps.includes(module) ||
|
||||
deps.some(dep => module.startsWith(`${dep}/`)) ||
|
||||
module.startsWith('eslint/') ||
|
||||
module.startsWith('typescript/')
|
||||
),
|
||||
),
|
||||
),
|
||||
])
|
||||
.filter(([, modules]) => modules.length > 0),
|
||||
);
|
||||
|
||||
console.log(files);
|
38
src/commits.json
Normal file
38
src/commits.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"eslint-plugin-import": {
|
||||
"hash": "f77ceb679d59ced5d9a633123385470a9eea10d9",
|
||||
"date": "2024-04-07T12:55:28+12:00",
|
||||
"committer": "Jordan Harband",
|
||||
"subject": "[actions] cancel in-progress runs on PR updates"
|
||||
},
|
||||
"eslint-import-resolver-typescript": {
|
||||
"hash": "7a02ac08b5aaac8c217f0e87142f97eafcc38fbc",
|
||||
"date": "2024-04-01T01:06:20+00:00",
|
||||
"committer": "GitHub",
|
||||
"subject": "chore(deps): update dependency npm-run-all2 to ^5.0.2 (#277)"
|
||||
},
|
||||
"eslint-plugin-jsx-a11y": {
|
||||
"hash": "0d5321a5457c5f0da0ca216053cc5b4f571b53ae",
|
||||
"date": "2024-01-27T22:18:19-08:00",
|
||||
"committer": "Jordan Harband",
|
||||
"subject": "[Deps] update `@babel/runtime`, `safe-regex-test`"
|
||||
},
|
||||
"eslint-plugin-n": {
|
||||
"hash": "eb11b5b35a6a797dc7fba6df53b1c4dada3a2a55",
|
||||
"date": "2024-04-17T17:40:32+08:00",
|
||||
"committer": "GitHub",
|
||||
"subject": "chore: upgrade globals v15 (#241)"
|
||||
},
|
||||
"eslint-plugin-react": {
|
||||
"hash": "4467db503e38b9356517cf6926d11be544ccf4b1",
|
||||
"date": "2024-03-16T12:54:58+09:00",
|
||||
"committer": "Jordan Harband",
|
||||
"subject": "[Fix] `boolean-prop-naming`: avoid a crash with a non-TSTypeReference type"
|
||||
},
|
||||
"jsx-ast-utils": {
|
||||
"hash": "5943318eaf23764eec3ff397ebb969613d728a95",
|
||||
"date": "2023-07-28T18:34:04-07:00",
|
||||
"committer": "Jordan Harband",
|
||||
"subject": "v3.3.5"
|
||||
}
|
||||
}
|
141
src/index.ts
141
src/index.ts
@ -1,23 +1,42 @@
|
||||
/// <reference path="./modules.d.ts" />
|
||||
import './redirect';
|
||||
import fs from 'node:fs';
|
||||
import type { Rule } from 'eslint';
|
||||
import type { ESLintUtils } from '@typescript-eslint/utils';
|
||||
import type { ESLintConfig, Rules } from 'eslint-define-config';
|
||||
import { typescriptRules } from './presets/typescript';
|
||||
import { unicornRules } from './presets/unicorn';
|
||||
import { eslintRules } from './presets/eslint';
|
||||
import { reactRules } from './presets/react';
|
||||
import { importRules } from './presets/import';
|
||||
import { jsDocRules } from './presets/jsdoc';
|
||||
import { graphqlRules } from './presets/graphql';
|
||||
import { localRules } from './presets/local';
|
||||
import { error, warn, off } from './constants';
|
||||
import { tailwindRules } from './presets/tailwind';
|
||||
|
||||
export { error, warn, off };
|
||||
|
||||
const unique = <T>(arr: T[]): T[] => [...new Set(arr)];
|
||||
declare global {
|
||||
interface Array<T> {
|
||||
filter(
|
||||
predicate: BooleanConstructor,
|
||||
): Exclude<T, null | undefined | false | '' | 0>[];
|
||||
}
|
||||
}
|
||||
|
||||
const unique = (...arr: (false | undefined | string | string[])[]): string[] => [
|
||||
...new Set(arr.flat(1).filter(Boolean)),
|
||||
];
|
||||
|
||||
const ensureArray = <T>(value?: T | T[]): T[] =>
|
||||
value == null ? [] : Array.isArray(value) ? value : [value];
|
||||
|
||||
type RuleLevel = 'error' | 'warn' | 'off' | 0 | 1 | 2;
|
||||
type RuleEntry<Options> = RuleLevel | [RuleLevel, Partial<Options>];
|
||||
|
||||
declare module 'eslint-define-config/src/rules/react/no-unknown-property.d.ts' {
|
||||
export interface NoUnknownPropertyOption {
|
||||
declare module 'eslint-define-config' {
|
||||
interface NoUnknownPropertyOption {
|
||||
extends: ('next' | 'emotion')[];
|
||||
}
|
||||
}
|
||||
@ -36,16 +55,30 @@ export interface LocalRuleOptions {
|
||||
|
||||
export type RuleOptions = Rules & Partial<LocalRuleOptions>;
|
||||
|
||||
export interface CustomRule {
|
||||
rule: () => Promise<{
|
||||
default: Rule.RuleModule | ESLintUtils.RuleModule<string, unknown[]>;
|
||||
}>;
|
||||
options?: RuleLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* ESLint Configuration.
|
||||
* @see [ESLint Configuration](https://eslint.org/docs/latest/user-guide/configuring/)
|
||||
*/
|
||||
type Config = Omit<ESLintConfig, 'rules'> & {
|
||||
export type InputConfig = Omit<ESLintConfig, 'rules'> & {
|
||||
/**
|
||||
* Rules.
|
||||
* @see [Rules](https://eslint.org/docs/latest/user-guide/configuring/rules)
|
||||
*/
|
||||
rules?: RuleOptions;
|
||||
|
||||
/**
|
||||
* Glob pattern to find paths to custom rule files in JavaScript or TypeScript.
|
||||
* Note this must be a string literal or an array of string literals since
|
||||
* this is statically analyzed.
|
||||
*/
|
||||
customRuleFiles?: string | string[];
|
||||
};
|
||||
|
||||
/**
|
||||
@ -54,49 +87,69 @@ type Config = Omit<ESLintConfig, 'rules'> & {
|
||||
* By default, it includes `["@typescript-eslint", "import", "prettier"]` configs.
|
||||
* Additional bundled plugins include:
|
||||
*
|
||||
* 1. [react](https://github.com/jsx-eslint/eslint-plugin-react#list-of-supported-rules)
|
||||
* 2. [react-refresh](https://github.com/ArnaudBarre/eslint-plugin-react-refresh)
|
||||
* 3. [jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y#supported-rules)
|
||||
* 4. [unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn#rules)
|
||||
* 5. [n](https://github.com/eslint-community/eslint-plugin-n#-rules) (Node.js specific)
|
||||
* 1. [`react`](https://github.com/jsx-eslint/eslint-plugin-react#list-of-supported-rules)
|
||||
* (automatically enables
|
||||
* [`react-hooks`](https://github.com/facebook/react/tree/main/packages/eslint-plugin-react-hooks))
|
||||
* 2. [`react-refresh`](https://github.com/ArnaudBarre/eslint-plugin-react-refresh)
|
||||
* 3. [`jsx-a11y`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y#supported-rules)
|
||||
* 4. [`unicorn`](https://github.com/sindresorhus/eslint-plugin-unicorn#rules)
|
||||
* 5. [`n`](https://github.com/eslint-community/eslint-plugin-n#-rules) (Node.js specific)
|
||||
* 6. [`jsdoc`](https://github.com/gajus/eslint-plugin-jsdoc#rules)
|
||||
*
|
||||
* Non bundled:
|
||||
* 1. [`graphql`](https://the-guild.dev/graphql/eslint/rules)
|
||||
*/
|
||||
export function extendConfig({
|
||||
plugins,
|
||||
settings,
|
||||
rules,
|
||||
extends: _extends,
|
||||
overrides,
|
||||
...rest
|
||||
}: Config = {}): ESLintConfig {
|
||||
const hasReact = plugins?.includes('react');
|
||||
const hasReactRefresh = plugins?.includes('react-refresh');
|
||||
const hasUnicorn = plugins?.includes('unicorn');
|
||||
const hasNext = ensureArray(_extends).some(name => name.includes(':@next/next'));
|
||||
export function extendConfig(of: InputConfig = {}): ESLintConfig {
|
||||
const {
|
||||
plugins = [],
|
||||
settings,
|
||||
rules,
|
||||
extends: _extends,
|
||||
overrides,
|
||||
customRuleFiles,
|
||||
...rest
|
||||
} = of;
|
||||
|
||||
const result: Config = {
|
||||
const hasReact = plugins.includes('react');
|
||||
const hasReactRefresh = plugins.includes('react-refresh');
|
||||
const hasUnicorn = plugins.includes('unicorn');
|
||||
const hasJsDoc = plugins.includes('jsdoc');
|
||||
const hasGraphQL = plugins.includes('@graphql-eslint');
|
||||
const hasNext = ensureArray(_extends).some(name => name.includes(':@next/next'));
|
||||
const hasTailwind = ensureArray(_extends).some(name =>
|
||||
name.includes('plugin:tailwindcss/'),
|
||||
);
|
||||
|
||||
const ruleDir = false; // ?? findCacheDirectory({ name: '_eslint-rules' });
|
||||
if (ruleDir) {
|
||||
fs.rmSync(ruleDir, { recursive: true, force: true });
|
||||
fs.mkdirSync(ruleDir, { recursive: true });
|
||||
}
|
||||
|
||||
const result: InputConfig = {
|
||||
root: true,
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: unique(['@typescript-eslint', 'import', 'rules', ...(plugins ?? [])]),
|
||||
plugins: unique('@typescript-eslint', 'import', 'rules', plugins),
|
||||
env: { node: true, browser: true, es2023: true },
|
||||
reportUnusedDisableDirectives: true,
|
||||
parserOptions: {
|
||||
project: true,
|
||||
},
|
||||
extends: unique([
|
||||
extends: unique(
|
||||
'eslint:recommended',
|
||||
'prettier',
|
||||
'plugin:@typescript-eslint/recommended-type-checked',
|
||||
'plugin:import/errors',
|
||||
'plugin:import/typescript',
|
||||
...(hasReact
|
||||
? [
|
||||
'plugin:react/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
'plugin:jsx-a11y/recommended',
|
||||
]
|
||||
: []),
|
||||
...(_extends ?? []),
|
||||
]),
|
||||
hasReact && [
|
||||
'plugin:react/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
'plugin:jsx-a11y/recommended',
|
||||
],
|
||||
hasJsDoc && 'plugin:jsdoc/recommended-typescript',
|
||||
hasGraphQL && 'plugin:@graphql-eslint/recommended',
|
||||
_extends,
|
||||
),
|
||||
settings: {
|
||||
'import/parsers': {
|
||||
'@typescript-eslint/parser': ['.ts', '.tsx', '.mts', '.cts'],
|
||||
@ -113,13 +166,7 @@ export function extendConfig({
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: [
|
||||
'.eslintrc.js',
|
||||
'*.config.js',
|
||||
'index.js',
|
||||
'babel.config.js',
|
||||
'next.config.js',
|
||||
],
|
||||
files: ['.eslintrc.js', '.eslintrc.cjs', '*.config.js', 'index.js'],
|
||||
extends: ['plugin:@typescript-eslint/disable-type-checked'],
|
||||
rules: {
|
||||
'rules/restrict-template-expressions': off,
|
||||
@ -131,25 +178,33 @@ export function extendConfig({
|
||||
'@typescript-eslint/consistent-type-imports': off,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['repl.ts', 'scripts/**/*.ts'],
|
||||
rules: {
|
||||
'no-console': off,
|
||||
},
|
||||
},
|
||||
...(overrides ?? []),
|
||||
],
|
||||
rules: {
|
||||
...eslintRules,
|
||||
...typescriptRules,
|
||||
...importRules,
|
||||
...localRules,
|
||||
...(hasReact && {
|
||||
...reactRules,
|
||||
'react/no-unknown-property': [
|
||||
error,
|
||||
{ ignore: hasNext ? ['emotion', 'next'] : ['emotion'] },
|
||||
{ ignore: hasNext ? ['css', 'next'] : ['css'] },
|
||||
],
|
||||
}),
|
||||
...(hasReactRefresh && {
|
||||
'react-refresh/only-export-components': [warn, { allowConstantExport: true }],
|
||||
}),
|
||||
...(hasUnicorn && unicornRules),
|
||||
'rules/no-import-dot': error,
|
||||
'rules/restrict-template-expressions': error,
|
||||
...(hasJsDoc && jsDocRules),
|
||||
...(hasGraphQL && graphqlRules),
|
||||
...(hasTailwind && tailwindRules),
|
||||
...rules,
|
||||
},
|
||||
...rest,
|
||||
|
@ -1,18 +1,13 @@
|
||||
import type { ESLint } from 'eslint';
|
||||
import * as fs from 'node:fs';
|
||||
import { resolve, basename, extname } from 'node:path';
|
||||
|
||||
function tryRequire(candidates: string[]) {
|
||||
for (const candidate of candidates) {
|
||||
try {
|
||||
require(candidate);
|
||||
return;
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
import { glob } from 'fast-glob';
|
||||
import { parseModule } from 'esprima';
|
||||
import query from 'esquery';
|
||||
import type { Node, Property } from 'estree';
|
||||
|
||||
// https://github.com/gulpjs/interpret
|
||||
tryRequire([
|
||||
const transpilers = [
|
||||
'esbin/register',
|
||||
'esbuild-register',
|
||||
'ts-node/register/transpile-only',
|
||||
@ -20,19 +15,63 @@ tryRequire([
|
||||
'sucrase/register',
|
||||
'@babel/register',
|
||||
'coffeescript/register',
|
||||
]);
|
||||
];
|
||||
|
||||
const folders = resolve(process.cwd(), 'eslint-local-rules');
|
||||
const files = fs.readdirSync(folders);
|
||||
function tryRequire() {
|
||||
for (const candidate of transpilers) {
|
||||
try {
|
||||
require(candidate);
|
||||
return;
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
|
||||
const unwrapDefault = <T = any>(module: any): T => module.default ?? module;
|
||||
|
||||
const plugin: ESLint.Plugin = {
|
||||
rules: {},
|
||||
};
|
||||
|
||||
for (const file of files) {
|
||||
const name = basename(file, extname(file));
|
||||
const module = require(resolve(folders, file));
|
||||
plugin.rules![name] = module.default ?? module;
|
||||
function hydrateESTreeNode(n: Node): any {
|
||||
switch (n.type) {
|
||||
case 'Literal':
|
||||
return n.value;
|
||||
case 'ArrayExpression':
|
||||
return n.elements.filter(Boolean).map(hydrateESTreeNode);
|
||||
default:
|
||||
throw new Error(`Unsupported node type: ${n.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
function parseConfigFile(js: string) {
|
||||
const [node] = query(
|
||||
parseModule(js),
|
||||
'CallExpression[callee.name="extendConfig"] > ObjectExpression > Property[key.name="customRuleFiles"]',
|
||||
);
|
||||
return hydrateESTreeNode((node as Property).value);
|
||||
}
|
||||
|
||||
function main() {
|
||||
const rootDir = process.cwd();
|
||||
|
||||
const eslintConfigFile = ['.eslintrc.js', '.eslintrc.cjs']
|
||||
.map(file => resolve(rootDir, file))
|
||||
.find(file => fs.existsSync(file));
|
||||
|
||||
if (!eslintConfigFile) return;
|
||||
|
||||
const eslintConfig = fs.readFileSync(eslintConfigFile, 'utf8');
|
||||
const customRuleFiles = parseConfigFile(eslintConfig);
|
||||
if (!customRuleFiles?.length) return;
|
||||
|
||||
tryRequire();
|
||||
for (const file of glob.sync(customRuleFiles)) {
|
||||
const module = unwrapDefault(require(file));
|
||||
const name = module.name ?? basename(file, extname(file));
|
||||
plugin.rules![name] = module;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
export = plugin;
|
||||
|
21
src/types.d.ts → src/modules.d.ts
vendored
21
src/types.d.ts → src/modules.d.ts
vendored
@ -13,3 +13,24 @@ declare module '@typescript-eslint/utils/eslint-utils' {
|
||||
declare module '@typescript-eslint/utils/json-schema' {
|
||||
export * from '@typescript-eslint/utils/dist/json-schema';
|
||||
}
|
||||
declare module '@typescript-eslint/scope-manager' {
|
||||
export * from '@typescript-eslint/scope-manager/dist/index';
|
||||
}
|
||||
declare module '@typescript-eslint/types' {
|
||||
export * from '@typescript-eslint/types/dist/index';
|
||||
}
|
||||
|
||||
declare module 'module' {
|
||||
export function _resolveFilename(
|
||||
request: string,
|
||||
parent: {
|
||||
/**
|
||||
* Can be null if the parent id is 'internal/preload' (e.g. via --require)
|
||||
* which doesn't have a file path.
|
||||
*/
|
||||
filename: string | null;
|
||||
},
|
||||
isMain: boolean,
|
||||
options?: Record<PropertyKey, unknown>,
|
||||
): string;
|
||||
}
|
@ -57,3 +57,8 @@ export function* map<T, U>(
|
||||
yield callback(value);
|
||||
}
|
||||
}
|
||||
|
||||
// safe-regex-test/index.js
|
||||
export function safeRegexTest(regex: RegExp) {
|
||||
return (text: string) => regex.test(text);
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { error, warn, off } from '../constants';
|
||||
import { EslintRules } from 'eslint-define-config/src/rules/eslint';
|
||||
import { ESLintRules } from 'eslint-define-config/rules/eslint';
|
||||
|
||||
export const eslintRules: Partial<EslintRules> = {
|
||||
export const eslintRules: Partial<ESLintRules> = {
|
||||
'arrow-body-style': [error, 'as-needed'],
|
||||
'class-methods-use-this': off,
|
||||
'func-style': [error, 'declaration', { allowArrowFunctions: true }],
|
||||
'no-async-promise-executor': off,
|
||||
'no-case-declarations': off,
|
||||
'no-console': warn,
|
||||
|
4
src/presets/graphql.ts
Normal file
4
src/presets/graphql.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import { GraphQLRules } from 'eslint-define-config/rules/graphql-eslint';
|
||||
|
||||
// https://the-guild.dev/graphql/eslint/rules
|
||||
export const graphqlRules: Partial<GraphQLRules> = {};
|
@ -1,5 +1,5 @@
|
||||
import { error, off } from '../constants';
|
||||
import { ImportRules } from 'eslint-define-config/src/rules/import';
|
||||
import { ImportRules } from 'eslint-define-config/rules/import';
|
||||
|
||||
export const importRules: Partial<ImportRules> = {
|
||||
'import/export': off,
|
||||
|
3
src/presets/jsdoc.ts
Normal file
3
src/presets/jsdoc.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { JSDocRules } from 'eslint-define-config/rules/jsdoc';
|
||||
|
||||
export const jsDocRules: Partial<JSDocRules> = {};
|
@ -1,6 +1,7 @@
|
||||
import { error, off } from '../constants';
|
||||
import type { CustomRuleOptions } from 'eslint-define-config';
|
||||
import type { LocalRuleOptions } from '../index';
|
||||
import { error } from '../constants';
|
||||
|
||||
export const importRules: Partial<CustomRuleOptions> = {
|
||||
'local/no-import-dot': error,
|
||||
export const localRules: Partial<LocalRuleOptions> = {
|
||||
'rules/no-import-dot': error,
|
||||
'rules/restrict-template-expressions': error,
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { error, off } from '../constants';
|
||||
import { ReactRules } from 'eslint-define-config/src/rules/react';
|
||||
import { ReactRules } from 'eslint-define-config/rules/react';
|
||||
|
||||
export const reactRules: Partial<ReactRules> = {
|
||||
'react/display-name': off,
|
||||
|
5
src/presets/tailwind.ts
Normal file
5
src/presets/tailwind.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { off } from '../constants';
|
||||
|
||||
export const tailwindRules = {
|
||||
'tailwindcss/no-custom-classname': off,
|
||||
} as const;
|
@ -1,5 +1,5 @@
|
||||
import { error, off, warn } from '../constants';
|
||||
import type { TypeScriptRules } from 'eslint-define-config/src/rules/typescript-eslint';
|
||||
import type { TypeScriptRules } from 'eslint-define-config/rules/typescript-eslint';
|
||||
|
||||
export const typescriptRules: Partial<TypeScriptRules> = {
|
||||
'@typescript-eslint/ban-ts-comment': [
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { error, warn } from '../constants';
|
||||
import { UnicornRules } from 'eslint-define-config/src/rules/unicorn';
|
||||
import { UnicornRules } from 'eslint-define-config/rules/unicorn';
|
||||
|
||||
const suggest = (suggest: string) => ({ suggest, fix: false });
|
||||
|
||||
|
37
src/prettier.ts
Normal file
37
src/prettier.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import type { Config } from 'prettier';
|
||||
|
||||
const prettier: Config = {
|
||||
arrowParens: 'avoid',
|
||||
tabWidth: 2,
|
||||
printWidth: 90,
|
||||
semi: true,
|
||||
singleQuote: true,
|
||||
trailingComma: 'all',
|
||||
plugins: [],
|
||||
};
|
||||
|
||||
export default function defineConfig({
|
||||
tailwind,
|
||||
...config
|
||||
}: Partial<Config> & {
|
||||
tailwind?: boolean;
|
||||
}) {
|
||||
const result: Config = {
|
||||
...prettier,
|
||||
...config,
|
||||
};
|
||||
|
||||
if (tailwind) {
|
||||
ensureHas(result.plugins!, 'prettier-plugin-tailwindcss');
|
||||
result.tailwindAttributes ??= ['css'];
|
||||
result.tailwindFunctions ??= ['tw'];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function ensureHas<T>(list: T[], item: T) {
|
||||
if (!list.includes(item)) {
|
||||
list.push(item);
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import Module from 'module';
|
||||
const { name } = [require][0]('./package.json');
|
||||
|
||||
const _resolveFilename = (Module as any)._resolveFilename;
|
||||
const _resolveFilename = Module._resolveFilename;
|
||||
const alias = new Set([
|
||||
'eslint-import-resolver-typescript',
|
||||
'eslint-plugin-import',
|
||||
@ -13,9 +13,14 @@ const alias = new Set([
|
||||
'eslint-plugin-rules',
|
||||
]);
|
||||
|
||||
(Module as any)._resolveFilename = function (module: string, ...args: any[]) {
|
||||
if (alias.has(module)) {
|
||||
module = `${name}/${module}`;
|
||||
type CDR<T> = T extends [any, ...infer R] ? R : [];
|
||||
|
||||
Module._resolveFilename = function (
|
||||
request: string,
|
||||
...args: CDR<Parameters<typeof _resolveFilename>>
|
||||
) {
|
||||
if (alias.has(request)) {
|
||||
request = `${name}/${request}`;
|
||||
}
|
||||
return _resolveFilename(module, ...args);
|
||||
return _resolveFilename(request, ...args);
|
||||
};
|
||||
|
@ -1,15 +1,15 @@
|
||||
import type { Rule } from 'eslint';
|
||||
import type { ESLintUtils } from '@typescript-eslint/utils';
|
||||
|
||||
import noEmptyObjectLiteral from './no-empty-object-literal';
|
||||
import noImportDot from './no-import-dot';
|
||||
import noEmptyObjectLiteral from './no-empty-object-literal';
|
||||
import restrictTemplateExpressions from './restrict-template-expressions';
|
||||
|
||||
export const rules: Record<
|
||||
string,
|
||||
Rule.RuleModule | ESLintUtils.RuleModule<string, unknown[]>
|
||||
> = {
|
||||
'no-empty-object-literal': noEmptyObjectLiteral,
|
||||
'no-import-dot': noImportDot,
|
||||
'no-empty-object-literal': noEmptyObjectLiteral,
|
||||
'restrict-template-expressions': restrictTemplateExpressions,
|
||||
};
|
||||
|
@ -1,16 +1,15 @@
|
||||
import type { Rule } from 'eslint';
|
||||
import { defineRule } from '../types';
|
||||
|
||||
const rule: Rule.RuleModule = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
'Ban assignment of empty object literals `{}` and replace them with `Object.create(null)`',
|
||||
category: 'Best Practices',
|
||||
recommended: true,
|
||||
},
|
||||
fixable: 'code',
|
||||
export default defineRule({
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
'Ban assignment of empty object literals `{}` and replace them with `Object.create(null)`',
|
||||
category: 'Best Practices',
|
||||
recommended: true,
|
||||
},
|
||||
fixable: 'code',
|
||||
|
||||
create: context => ({
|
||||
AssignmentExpression(node) {
|
||||
if (
|
||||
@ -27,6 +26,4 @@ const rule: Rule.RuleModule = {
|
||||
}
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
export default rule;
|
||||
});
|
||||
|
26
src/types.ts
Normal file
26
src/types.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import type { Rule } from 'eslint';
|
||||
import type { ESLintUtils } from '@typescript-eslint/utils';
|
||||
|
||||
export function defineRules(rules: {
|
||||
[ruleName: string]: Rule.RuleModule | ESLintUtils.RuleModule<string, unknown[]>;
|
||||
}) {
|
||||
return rules;
|
||||
}
|
||||
|
||||
export function defineRule({
|
||||
name,
|
||||
create,
|
||||
...meta
|
||||
}: Rule.RuleMetaData & {
|
||||
name?: string;
|
||||
create: (context: Rule.RuleContext) => Rule.RuleListener;
|
||||
}): Rule.RuleModule {
|
||||
const module: Rule.RuleModule = {
|
||||
meta,
|
||||
create,
|
||||
};
|
||||
if (name != null) {
|
||||
Object.defineProperty(module, 'name', { value: name });
|
||||
}
|
||||
return module;
|
||||
}
|
171
src/types/config/env.d.ts
vendored
Normal file
171
src/types/config/env.d.ts
vendored
Normal file
@ -0,0 +1,171 @@
|
||||
/**
|
||||
* An environment provides predefined global variables.
|
||||
*
|
||||
* @see [Environments](https://eslint.org/docs/user-guide/configuring/language-options#specifying-environments)
|
||||
*/
|
||||
export interface Environments extends Partial<Record<string, boolean>> {
|
||||
/**
|
||||
* Browser global variables.
|
||||
*/
|
||||
browser?: boolean;
|
||||
|
||||
/**
|
||||
* Node.js global variables and Node.js scoping.
|
||||
*/
|
||||
node?: boolean;
|
||||
|
||||
/**
|
||||
* CommonJS global variables and CommonJS scoping (use this for browser-only code that uses Browserify/WebPack).
|
||||
*/
|
||||
commonjs?: boolean;
|
||||
|
||||
/**
|
||||
* Globals common to both Node.js and Browser.
|
||||
*/
|
||||
'shared-node-browser'?: boolean;
|
||||
|
||||
/**
|
||||
* Enable all ECMAScript 6 features except for modules (this automatically sets the `ecmaVersion` parser option to 6).
|
||||
*/
|
||||
es6?: boolean;
|
||||
|
||||
/**
|
||||
* Adds all ECMAScript 2016 globals and automatically sets the `ecmaVersion` parser option to 7.
|
||||
*/
|
||||
es2016?: boolean;
|
||||
|
||||
/**
|
||||
* Adds all ECMAScript 2017 globals and automatically sets the `ecmaVersion` parser option to 8.
|
||||
*/
|
||||
es2017?: boolean;
|
||||
|
||||
/**
|
||||
* Adds all ECMAScript 2018 globals and automatically sets the `ecmaVersion` parser option to 9.
|
||||
*/
|
||||
es2018?: boolean;
|
||||
|
||||
/**
|
||||
* Adds all ECMAScript 2019 globals and automatically sets the `ecmaVersion` parser option to 10.
|
||||
*/
|
||||
es2019?: boolean;
|
||||
|
||||
/**
|
||||
* Adds all ECMAScript 2020 globals and automatically sets the `ecmaVersion` parser option to 11.
|
||||
*/
|
||||
es2020?: boolean;
|
||||
|
||||
/**
|
||||
* Adds all ECMAScript 2021 globals and automatically sets the `ecmaVersion` parser option to 12.
|
||||
*/
|
||||
es2021?: boolean;
|
||||
|
||||
/**
|
||||
* Adds all ECMAScript 2022 globals and automatically sets the `ecmaVersion` parser option to 13.
|
||||
*/
|
||||
es2022?: boolean;
|
||||
|
||||
/**
|
||||
* Adds all ECMAScript 2023 globals and automatically sets the `ecmaVersion` parser option to 14.
|
||||
*/
|
||||
es2023?: boolean;
|
||||
|
||||
/**
|
||||
* Web workers global variables.
|
||||
*/
|
||||
worker?: boolean;
|
||||
|
||||
/**
|
||||
* Defines `require()` and `define()` as global variables as per the amd spec.
|
||||
*/
|
||||
amd?: boolean;
|
||||
|
||||
/**
|
||||
* Adds all of the Mocha testing global variables.
|
||||
*/
|
||||
mocha?: boolean;
|
||||
|
||||
/**
|
||||
* Adds all of the Jasmine testing global variables for version 1.3 and 2.0.
|
||||
*/
|
||||
jasmine?: boolean;
|
||||
|
||||
/**
|
||||
* Jest global variables.
|
||||
*/
|
||||
jest?: boolean;
|
||||
|
||||
/**
|
||||
* PhantomJS global variables.
|
||||
*/
|
||||
phantomjs?: boolean;
|
||||
|
||||
/**
|
||||
* Protractor global variables.
|
||||
*/
|
||||
protractor?: boolean;
|
||||
|
||||
/**
|
||||
* QUnit global variables.
|
||||
*/
|
||||
qunit?: boolean;
|
||||
|
||||
/**
|
||||
* jQuery global variables.
|
||||
*/
|
||||
jquery?: boolean;
|
||||
|
||||
/**
|
||||
* Prototype.js global variables.
|
||||
*/
|
||||
prototypejs?: boolean;
|
||||
|
||||
/**
|
||||
* ShellJS global variables.
|
||||
*/
|
||||
shelljs?: boolean;
|
||||
|
||||
/**
|
||||
* Meteor global variables.
|
||||
*/
|
||||
meteor?: boolean;
|
||||
|
||||
/**
|
||||
* MongoDB global variables.
|
||||
*/
|
||||
mongo?: boolean;
|
||||
|
||||
/**
|
||||
* AppleScript global variables.
|
||||
*/
|
||||
applescript?: boolean;
|
||||
|
||||
/**
|
||||
* Java 8 Nashorn global variables.
|
||||
*/
|
||||
nashorn?: boolean;
|
||||
|
||||
/**
|
||||
* Service Worker global variables.
|
||||
*/
|
||||
serviceworker?: boolean;
|
||||
|
||||
/**
|
||||
* Atom test helper globals.
|
||||
*/
|
||||
atomtest?: boolean;
|
||||
|
||||
/**
|
||||
* Ember test helper globals.
|
||||
*/
|
||||
embertest?: boolean;
|
||||
|
||||
/**
|
||||
* WebExtensions globals.
|
||||
*/
|
||||
webextensions?: boolean;
|
||||
|
||||
/**
|
||||
* GreaseMonkey globals.
|
||||
*/
|
||||
greasemonkey?: boolean;
|
||||
}
|
6
src/types/config/extends/eslint-plugin-eslint-comment.d.ts
vendored
Normal file
6
src/types/config/extends/eslint-plugin-eslint-comment.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Eslint EslintComments extends.
|
||||
*
|
||||
* @see [Eslint EslintComments extends](https://mysticatea.github.io/eslint-plugin-eslint-comments/#%F0%9F%93%96-usage)
|
||||
*/
|
||||
export type EslintCommentsExtends = 'plugin:eslint-comments/recommended';
|
11
src/types/config/extends/eslint-plugin-graphql.d.ts
vendored
Normal file
11
src/types/config/extends/eslint-plugin-graphql.d.ts
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Eslint GraphQL extends.
|
||||
*
|
||||
* @see [Eslint GraphQL extends](https://the-guild.dev/graphql/eslint/docs/configs)
|
||||
*/
|
||||
export type GraphqlExtends =
|
||||
| 'plugin:@graphql-eslint/operations-all'
|
||||
| 'plugin:@graphql-eslint/operations-recommended'
|
||||
| 'plugin:@graphql-eslint/relay'
|
||||
| 'plugin:@graphql-eslint/schema-all'
|
||||
| 'plugin:@graphql-eslint/schema-recommended';
|
9
src/types/config/extends/eslint-plugin-import.d.ts
vendored
Normal file
9
src/types/config/extends/eslint-plugin-import.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Eslint import extends.
|
||||
*
|
||||
* @see [Eslint import extends](https://github.com/benmosher/eslint-plugin-import#installation)
|
||||
*/
|
||||
export type ImportExtends =
|
||||
| 'plugin:import/errors'
|
||||
| 'plugin:import/warnings'
|
||||
| 'plugin:import/typescript';
|
6
src/types/config/extends/eslint-plugin-jsdoc.d.ts
vendored
Normal file
6
src/types/config/extends/eslint-plugin-jsdoc.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Eslint JSDoc extends.
|
||||
*
|
||||
* @see [Eslint JSDoc extends](https://github.com/gajus/eslint-plugin-jsdoc#configuration)
|
||||
*/
|
||||
export type JsdocExtends = 'plugin:jsdoc/recommended';
|
13
src/types/config/extends/eslint-plugin-jsonc.d.ts
vendored
Normal file
13
src/types/config/extends/eslint-plugin-jsonc.d.ts
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Eslint Jsonc extends.
|
||||
*
|
||||
* @see [Eslint Jsonc extends](https://github.com/ota-meshi/eslint-plugin-jsonc#configuration)
|
||||
*/
|
||||
export type JsoncExtends =
|
||||
| 'plugin:jsdoc/base'
|
||||
| 'plugin:jsdoc/recommended'
|
||||
| 'plugin:jsonc/recommended-with-json'
|
||||
| 'plugin:jsonc/recommended-with-jsonc'
|
||||
| 'plugin:jsonc/recommended-with-json5'
|
||||
| 'plugin:jsonc/prettier'
|
||||
| 'plugin:jsonc/all';
|
8
src/types/config/extends/eslint-plugin-jsx-a11y.d.ts
vendored
Normal file
8
src/types/config/extends/eslint-plugin-jsx-a11y.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Eslint JSX A11y extends.
|
||||
*
|
||||
* @see [Eslint JSX A11y extends](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y)
|
||||
*/
|
||||
export type JsxA11yExtends =
|
||||
| 'plugin:jsx-a11y/strict'
|
||||
| 'plugin:jsx-a11y/recommended';
|
10
src/types/config/extends/eslint-plugin-mdx.d.ts
vendored
Normal file
10
src/types/config/extends/eslint-plugin-mdx.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Eslint MDX extends.
|
||||
*
|
||||
* @see [Eslint MDX extends](https://github.com/mdx-js/eslint-mdx/tree/master/packages/eslint-plugin-mdx)
|
||||
*/
|
||||
export type MdxExtends =
|
||||
| 'plugin:mdx/base'
|
||||
| 'plugin:mdx/code-blocks'
|
||||
| 'plugin:mdx/overrides'
|
||||
| 'plugin:mdx/recommended';
|
9
src/types/config/extends/eslint-plugin-n.d.ts
vendored
Normal file
9
src/types/config/extends/eslint-plugin-n.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Eslint N (Node) extends.
|
||||
*
|
||||
* @see [Eslint N extends](https://github.com/eslint-community/eslint-plugin-n#-configs)
|
||||
*/
|
||||
export type NExtends =
|
||||
| 'plugin:n/recommended'
|
||||
| 'plugin:n/recommended-module'
|
||||
| 'plugin:n/recommended-script';
|
9
src/types/config/extends/eslint-plugin-node.d.ts
vendored
Normal file
9
src/types/config/extends/eslint-plugin-node.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Eslint Node extends.
|
||||
*
|
||||
* @see [Eslint Node extends](https://github.com/mysticatea/eslint-plugin-node#-configs)
|
||||
*/
|
||||
export type NodeExtends =
|
||||
| 'plugin:node/recommended'
|
||||
| 'plugin:node/recommended-module'
|
||||
| 'plugin:node/recommended-script';
|
6
src/types/config/extends/eslint-plugin-prettier.d.ts
vendored
Normal file
6
src/types/config/extends/eslint-plugin-prettier.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Eslint Prettier extends.
|
||||
*
|
||||
* @see [Eslint Prettier extends](https://github.com/prettier/eslint-plugin-prettier#recommended-configuration)
|
||||
*/
|
||||
export type PrettierExtends = 'plugin:prettier/recommended' | 'prettier';
|
6
src/types/config/extends/eslint-plugin-promise.d.ts
vendored
Normal file
6
src/types/config/extends/eslint-plugin-promise.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Eslint promise extends.
|
||||
*
|
||||
* @see [Eslint promise extends](https://github.com/eslint-community/eslint-plugin-promise#usage)
|
||||
*/
|
||||
export type PromiseExtends = 'plugin:promise/recommended';
|
6
src/types/config/extends/eslint-plugin-react-hooks.d.ts
vendored
Normal file
6
src/types/config/extends/eslint-plugin-react-hooks.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Eslint ReactHooks extends.
|
||||
*
|
||||
* @see [Eslint ReactHooks extends](https://github.com/facebook/react/tree/main/packages/eslint-plugin-react-hooks)
|
||||
*/
|
||||
export type ReactHooksExtends = 'plugin:react-hooks/recommended';
|
9
src/types/config/extends/eslint-plugin-react.d.ts
vendored
Normal file
9
src/types/config/extends/eslint-plugin-react.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Eslint React extends.
|
||||
*
|
||||
* @see [Eslint React extends](https://github.com/jsx-eslint/eslint-plugin-react)
|
||||
*/
|
||||
export type ReactExtends =
|
||||
| 'plugin:react/all'
|
||||
| 'plugin:react/jsx-runtime'
|
||||
| 'plugin:react/recommended';
|
6
src/types/config/extends/eslint-plugin-sonarjs.d.ts
vendored
Normal file
6
src/types/config/extends/eslint-plugin-sonarjs.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Eslint Sonarjs extends.
|
||||
*
|
||||
* @see [Eslint Sonarjs extends](https://github.com/SonarSource/eslint-plugin-sonarjs#available-configurations)
|
||||
*/
|
||||
export type SonarjsExtends = 'plugin:sonarjs/recommended';
|
11
src/types/config/extends/eslint-plugin-testing-library.d.ts
vendored
Normal file
11
src/types/config/extends/eslint-plugin-testing-library.d.ts
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Eslint TestingLibrary extends.
|
||||
*
|
||||
* @see [Eslint TestingLibrary extends](https://github.com/testing-library/eslint-plugin-testing-library)
|
||||
*/
|
||||
export type TestingLibraryExtends =
|
||||
| 'plugin:testing-library/angular'
|
||||
| 'plugin:testing-library/dom'
|
||||
| 'plugin:testing-library/marko'
|
||||
| 'plugin:testing-library/react'
|
||||
| 'plugin:testing-library/vue';
|
8
src/types/config/extends/eslint-plugin-unicorn.d.ts
vendored
Normal file
8
src/types/config/extends/eslint-plugin-unicorn.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Eslint Unicorn extends.
|
||||
*
|
||||
* @see [Eslint Unicorn extends](https://github.com/sindresorhus/eslint-plugin-unicorn)
|
||||
*/
|
||||
export type UnicornExtends =
|
||||
| 'plugin:unicorn/recommended'
|
||||
| 'plugin:unicorn/all';
|
6
src/types/config/extends/eslint-plugin-vitest.d.ts
vendored
Normal file
6
src/types/config/extends/eslint-plugin-vitest.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Eslint Vitest extends.
|
||||
*
|
||||
* @see [Eslint Vitest extends](https://eslint.vuejs.org/user-guide/#usage)
|
||||
*/
|
||||
export type VitestExtends = 'plugin:vitest/all' | 'plugin:vitest/recommended';
|
13
src/types/config/extends/eslint-plugin-vue-pug.d.ts
vendored
Normal file
13
src/types/config/extends/eslint-plugin-vue-pug.d.ts
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Eslint Vue Pug extends.
|
||||
*
|
||||
* @see [Eslint Vue Pug extends](https://github.com/rashfael/eslint-plugin-vue-pug#usage)
|
||||
*/
|
||||
export type VuePugExtends =
|
||||
| 'plugin:vue-pug/base'
|
||||
| 'plugin:vue-pug/vue3-essential'
|
||||
| 'plugin:vue-pug/vue3-strongly-recommended'
|
||||
| 'plugin:vue-pug/vue3-recommended'
|
||||
| 'plugin:vue-pug/essential'
|
||||
| 'plugin:vue-pug/strongly-recommended'
|
||||
| 'plugin:vue-pug/recommended';
|
13
src/types/config/extends/eslint-plugin-vue.d.ts
vendored
Normal file
13
src/types/config/extends/eslint-plugin-vue.d.ts
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Eslint Vue extends.
|
||||
*
|
||||
* @see [Eslint Vue extends](https://eslint.vuejs.org/user-guide/#usage)
|
||||
*/
|
||||
export type VueExtends =
|
||||
| 'plugin:vue/base'
|
||||
| 'plugin:vue/vue3-essential'
|
||||
| 'plugin:vue/vue3-strongly-recommended'
|
||||
| 'plugin:vue/vue3-recommended'
|
||||
| 'plugin:vue/essential'
|
||||
| 'plugin:vue/strongly-recommended'
|
||||
| 'plugin:vue/recommended';
|
4
src/types/config/extends/eslint.d.ts
vendored
Normal file
4
src/types/config/extends/eslint.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Eslint extends.
|
||||
*/
|
||||
export type EslintExtends = 'eslint:recommended' | 'eslint:all';
|
82
src/types/config/extends/index.d.ts
vendored
Normal file
82
src/types/config/extends/index.d.ts
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
import type { LiteralUnion } from '../../utility-types';
|
||||
import type { EslintExtends } from './eslint';
|
||||
import type { EslintCommentsExtends } from './eslint-plugin-eslint-comment';
|
||||
import type { GraphqlExtends } from './eslint-plugin-graphql';
|
||||
import type { ImportExtends } from './eslint-plugin-import';
|
||||
import type { JsdocExtends } from './eslint-plugin-jsdoc';
|
||||
import type { JsoncExtends } from './eslint-plugin-jsonc';
|
||||
import type { MdxExtends } from './eslint-plugin-mdx';
|
||||
import type { NExtends } from './eslint-plugin-n';
|
||||
import type { NodeExtends } from './eslint-plugin-node';
|
||||
import type { PrettierExtends } from './eslint-plugin-prettier';
|
||||
import type { PromiseExtends } from './eslint-plugin-promise';
|
||||
import type { ReactExtends } from './eslint-plugin-react';
|
||||
import type { ReactHooksExtends } from './eslint-plugin-react-hooks';
|
||||
import type { SonarjsExtends } from './eslint-plugin-sonarjs';
|
||||
import type { TestingLibraryExtends } from './eslint-plugin-testing-library';
|
||||
import type { UnicornExtends } from './eslint-plugin-unicorn';
|
||||
import type { VitestExtends } from './eslint-plugin-vitest';
|
||||
import type { VueExtends } from './eslint-plugin-vue';
|
||||
import type { VuePugExtends } from './eslint-plugin-vue-pug';
|
||||
import type { IntlifyVueI18nExtends } from './intlify-vue-i18n';
|
||||
import type { TypescriptEslintExtends } from './typescript-eslint';
|
||||
|
||||
/**
|
||||
* This is a special exported interface for other packages to declare
|
||||
* additional extensions that should bail out for eslint extensions. For example
|
||||
* `'@typescript-eslint/eslint-plugin'` can declare it like so in its `d.ts`:
|
||||
*
|
||||
* ```ts
|
||||
* declare module 'eslint-define-config' {
|
||||
* export interface CustomExtends {
|
||||
* 'plugin:@typescript-eslint/all': void;
|
||||
* 'plugin:@typescript-eslint/base': void;
|
||||
* 'plugin:@typescript-eslint/disable-type-checked': void;
|
||||
* 'plugin:@typescript-eslint/eslint-recommended': void;
|
||||
* 'plugin:@typescript-eslint/recommended-type-checked': void;
|
||||
* 'plugin:@typescript-eslint/recommended': void;
|
||||
* 'plugin:@typescript-eslint/strict-type-checked': void;
|
||||
* 'plugin:@typescript-eslint/strict': void;
|
||||
* 'plugin:@typescript-eslint/stylistic-type-checked': void;
|
||||
* 'plugin:@typescript-eslint/stylistic': void;
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export interface CustomExtends {}
|
||||
|
||||
/**
|
||||
* All known extends.
|
||||
*/
|
||||
export type KnownExtends = LiteralUnion<
|
||||
| EslintCommentsExtends
|
||||
| EslintExtends
|
||||
| GraphqlExtends
|
||||
| ImportExtends
|
||||
| IntlifyVueI18nExtends
|
||||
| JsdocExtends
|
||||
| JsoncExtends
|
||||
| MdxExtends
|
||||
| NExtends
|
||||
| NodeExtends
|
||||
| PrettierExtends
|
||||
| PromiseExtends
|
||||
| ReactExtends
|
||||
| ReactHooksExtends
|
||||
| SonarjsExtends
|
||||
| TestingLibraryExtends
|
||||
| TypescriptEslintExtends
|
||||
| UnicornExtends
|
||||
| VitestExtends
|
||||
| VueExtends
|
||||
| VuePugExtends
|
||||
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
||||
| keyof CustomExtends
|
||||
>;
|
||||
|
||||
/**
|
||||
* Extending Configuration Files.
|
||||
*
|
||||
* @see [Extends](https://eslint.org/docs/user-guide/configuring/configuration-files#extending-configuration-files)
|
||||
*/
|
||||
export type Extends = KnownExtends | KnownExtends[];
|
6
src/types/config/extends/intlify-vue-i18n.d.ts
vendored
Normal file
6
src/types/config/extends/intlify-vue-i18n.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Eslint Intlify VueI18n extends.
|
||||
*
|
||||
* @see [Eslint Intlify VueI18n extends](https://eslint-plugin-vue-i18n.intlify.dev/started.html)
|
||||
*/
|
||||
export type IntlifyVueI18nExtends = 'plugin:@intlify/vue-i18n/recommended';
|
17
src/types/config/extends/typescript-eslint.d.ts
vendored
Normal file
17
src/types/config/extends/typescript-eslint.d.ts
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Typescript eslint extends.
|
||||
*
|
||||
* @see [Typescript eslint extends](https://typescript-eslint.io/linting/configs#recommended-configurations)
|
||||
*/
|
||||
export type TypescriptEslintExtends =
|
||||
| 'plugin:@typescript-eslint/all'
|
||||
| 'plugin:@typescript-eslint/base'
|
||||
| 'plugin:@typescript-eslint/disable-type-checked'
|
||||
| 'plugin:@typescript-eslint/eslint-recommended'
|
||||
| 'plugin:@typescript-eslint/recommended-requiring-type-checking' // this requiring-type-checking is deprecated and only for @typescript-eslint/eslint-plugin@v5
|
||||
| 'plugin:@typescript-eslint/recommended-type-checked'
|
||||
| 'plugin:@typescript-eslint/recommended'
|
||||
| 'plugin:@typescript-eslint/strict-type-checked'
|
||||
| 'plugin:@typescript-eslint/strict'
|
||||
| 'plugin:@typescript-eslint/stylistic-type-checked'
|
||||
| 'plugin:@typescript-eslint/stylistic';
|
121
src/types/config/index.d.ts
vendored
Normal file
121
src/types/config/index.d.ts
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
import type { Parser, ParserOptions } from '../parser-options';
|
||||
import type { Rules } from '../rules';
|
||||
import type { Environments } from './env';
|
||||
import type { Extends } from './extends';
|
||||
import type { Overrides } from './overrides';
|
||||
import type { Plugin } from './plugin';
|
||||
import type { Settings } from './settings';
|
||||
|
||||
/**
|
||||
* ESLint Configuration.
|
||||
*
|
||||
* @see [ESLint Configuration](https://eslint.org/docs/latest/user-guide/configuring/)
|
||||
*/
|
||||
export interface ESLintConfig {
|
||||
/**
|
||||
* @see [Using Configuration Files](https://eslint.org/docs/latest/user-guide/configuring/configuration-files#using-configuration-files)
|
||||
*/
|
||||
root?: boolean;
|
||||
|
||||
/**
|
||||
* Tell ESLint to ignore specific files and directories.
|
||||
*
|
||||
* @see [Ignore Patterns](https://eslint.org/docs/latest/user-guide/configuring/ignoring-code)
|
||||
*/
|
||||
ignorePatterns?: string[];
|
||||
|
||||
/**
|
||||
* An environment provides predefined global variables.
|
||||
*
|
||||
* @see [Environments](https://eslint.org/docs/latest/user-guide/configuring/language-options#specifying-environments)
|
||||
*/
|
||||
env?: Environments;
|
||||
|
||||
/**
|
||||
* Extending Configuration Files.
|
||||
*
|
||||
* @see [Extends](https://eslint.org/docs/latest/user-guide/configuring/configuration-files#extending-configuration-files)
|
||||
*/
|
||||
extends?: Extends;
|
||||
|
||||
/**
|
||||
* Specifying Globals.
|
||||
*
|
||||
* @see [Globals](https://eslint.org/docs/latest/user-guide/configuring/language-options#specifying-globals)
|
||||
*/
|
||||
globals?: Record<
|
||||
string,
|
||||
'readonly' | 'writable' | false | 'readable' | true | 'writeable' | 'off'
|
||||
>;
|
||||
|
||||
/**
|
||||
* Parser.
|
||||
*
|
||||
* @see [Working with Custom Parsers](https://eslint.org/docs/latest/developer-guide/working-with-custom-parsers)
|
||||
* @see [Specifying Parser](https://eslint.org/docs/latest/user-guide/configuring/plugins#configure-a-parser)
|
||||
*/
|
||||
parser?: Parser;
|
||||
|
||||
/**
|
||||
* Parser Options.
|
||||
*
|
||||
* @see [Working with Custom Parsers](https://eslint.org/docs/latest/developer-guide/working-with-custom-parsers)
|
||||
* @see [Specifying Parser Options](https://eslint.org/docs/latest/user-guide/configuring/language-options#specifying-parser-options)
|
||||
*/
|
||||
parserOptions?: ParserOptions;
|
||||
|
||||
/**
|
||||
* Which third-party plugins define additional rules, environments, configs, etc. for ESLint to use.
|
||||
*
|
||||
* @see [Configuring Plugins](https://eslint.org/docs/latest/user-guide/configuring/plugins#configure-plugins)
|
||||
*/
|
||||
plugins?: Plugin[];
|
||||
|
||||
/**
|
||||
* Specifying Processor.
|
||||
*
|
||||
* @see [processor](https://eslint.org/docs/latest/user-guide/configuring/plugins#specify-a-processor)
|
||||
*/
|
||||
processor?: string;
|
||||
|
||||
/**
|
||||
* Rules.
|
||||
*
|
||||
* @see [Rules](https://eslint.org/docs/latest/user-guide/configuring/rules)
|
||||
*/
|
||||
rules?: Partial<Rules>;
|
||||
|
||||
/**
|
||||
* Overrides.
|
||||
*
|
||||
* @see [How do overrides work](https://eslint.org/docs/latest/user-guide/configuring/configuration-files#how-do-overrides-work)
|
||||
*/
|
||||
overrides?: Overrides;
|
||||
|
||||
/**
|
||||
* Settings.
|
||||
*
|
||||
* @see [Settings](https://eslint.org/docs/latest/user-guide/configuring/configuration-files#adding-shared-settings)
|
||||
*/
|
||||
settings?: Settings;
|
||||
|
||||
/**
|
||||
* Disabling Inline Comments.
|
||||
*
|
||||
* @see [Disabling Inline Comments](https://eslint.org/docs/latest/user-guide/configuring/rules#disabling-inline-comments)
|
||||
*/
|
||||
noInlineConfig?: boolean;
|
||||
|
||||
/**
|
||||
* Report unused `ESLint-disable` comments.
|
||||
*
|
||||
* @see [Report unused `ESLint-disable` comments](https://eslint.org/docs/latest/user-guide/configuring/rules#report-unused-eslint-disable-comments)
|
||||
*/
|
||||
reportUnusedDisableDirectives?: boolean;
|
||||
}
|
||||
|
||||
export * from './env';
|
||||
export * from './extends';
|
||||
export * from './overrides';
|
||||
export * from './plugin';
|
||||
export * from './settings';
|
96
src/types/config/overrides.d.ts
vendored
Normal file
96
src/types/config/overrides.d.ts
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
import type { Parser, ParserOptions } from '../parser-options';
|
||||
import type { Rules } from '../rules';
|
||||
import type { Environments } from './env';
|
||||
import type { Extends } from './extends';
|
||||
import type { Plugin } from './plugin';
|
||||
import type { Settings } from './settings';
|
||||
|
||||
/**
|
||||
* OverrideConfigData.
|
||||
*/
|
||||
export interface Override {
|
||||
/**
|
||||
* The glob patterns for target files.
|
||||
*/
|
||||
// https://github.com/eslint/eslint/blob/762a8727fb3b5619cff900826053b643ca5f1162/lib/shared/types.js#L61
|
||||
files: string[] | string;
|
||||
|
||||
/**
|
||||
* The glob patterns for excluded files.
|
||||
*/
|
||||
// https://github.com/eslint/eslint/blob/762a8727fb3b5619cff900826053b643ca5f1162/lib/shared/types.js#L59
|
||||
excludedFiles?: string | string[];
|
||||
|
||||
/**
|
||||
* An environment provides predefined global variables.
|
||||
*
|
||||
* @see [Environments](https://eslint.org/docs/user-guide/configuring/language-options#specifying-environments)
|
||||
*/
|
||||
env?: Environments;
|
||||
|
||||
/**
|
||||
* Extending Configuration Files.
|
||||
*
|
||||
* @see [Extends](https://eslint.org/docs/user-guide/configuring/configuration-files#extending-configuration-files)
|
||||
*/
|
||||
extends?: Extends;
|
||||
|
||||
/**
|
||||
* Specifying Globals.
|
||||
*
|
||||
* @see [Globals](https://eslint.org/docs/latest/user-guide/configuring/language-options#specifying-globals)
|
||||
*/
|
||||
globals?: Record<
|
||||
string,
|
||||
'readonly' | 'writable' | false | 'readable' | true | 'writeable' | 'off'
|
||||
>;
|
||||
|
||||
/**
|
||||
* Parser.
|
||||
*
|
||||
* @see [Working with Custom Parsers](https://eslint.org/docs/developer-guide/working-with-custom-parsers)
|
||||
* @see [Specifying Parser](https://eslint.org/docs/user-guide/configuring/plugins#specifying-parser)
|
||||
*/
|
||||
parser?: Parser;
|
||||
|
||||
/**
|
||||
* Parser Options.
|
||||
*
|
||||
* @see [Working with Custom Parsers](https://eslint.org/docs/developer-guide/working-with-custom-parsers)
|
||||
* @see [Specifying Parser Options](https://eslint.org/docs/user-guide/configuring/language-options#specifying-parser-options)
|
||||
*/
|
||||
parserOptions?: ParserOptions;
|
||||
|
||||
/**
|
||||
* Which third-party plugins define additional rules, environments, configs, etc. for ESLint to use.
|
||||
*
|
||||
* @see [Configuring Plugins](https://eslint.org/docs/user-guide/configuring/plugins#configuring-plugins)
|
||||
*/
|
||||
plugins?: Plugin[];
|
||||
|
||||
/**
|
||||
* Specifying Processor.
|
||||
*
|
||||
* @see [processor](https://eslint.org/docs/user-guide/configuring/plugins#specifying-processor)
|
||||
*/
|
||||
processor?: string;
|
||||
|
||||
/**
|
||||
* Rules.
|
||||
*
|
||||
* @see [Rules](https://eslint.org/docs/user-guide/configuring/rules)
|
||||
*/
|
||||
rules?: Partial<Rules>;
|
||||
|
||||
/**
|
||||
* Settings.
|
||||
*
|
||||
* @see [Settings](https://eslint.org/docs/user-guide/configuring/configuration-files#adding-shared-settings)
|
||||
*/
|
||||
settings?: Settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides.
|
||||
*/
|
||||
export type Overrides = Override[];
|
40
src/types/config/plugin.d.ts
vendored
Normal file
40
src/types/config/plugin.d.ts
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
import type { LiteralUnion } from '../utility-types';
|
||||
|
||||
/**
|
||||
* This is a special exported interface for other packages to declare
|
||||
* additional plugins that should bail out for eslint plugins. For example
|
||||
* `'@typescript-eslint/eslint-plugin'` can declare it like so in its `d.ts`:
|
||||
*
|
||||
* ```ts
|
||||
* declare module 'eslint-define-config' {
|
||||
* export interface CustomPlugins {
|
||||
* '@typescript-eslint': void;
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export interface CustomPlugins {}
|
||||
|
||||
/** Plugin. */
|
||||
export type Plugin = LiteralUnion<
|
||||
| '@graphql-eslint'
|
||||
| '@typescript-eslint'
|
||||
| 'deprecation'
|
||||
| 'import'
|
||||
| 'inclusive-language'
|
||||
| 'jsdoc'
|
||||
| 'jsx-a11y'
|
||||
| 'mdx'
|
||||
| 'prettier'
|
||||
| 'promise'
|
||||
| 'react-hooks'
|
||||
| 'react'
|
||||
| 'sonarjs'
|
||||
| 'spellcheck'
|
||||
| 'testing-library'
|
||||
| 'unicorn'
|
||||
| 'vitest'
|
||||
| 'vue'
|
||||
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
||||
| keyof CustomPlugins
|
||||
>;
|
66
src/types/config/settings/import.d.ts
vendored
Normal file
66
src/types/config/settings/import.d.ts
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
import type { Parser } from '../../parser-options';
|
||||
|
||||
/**
|
||||
* Import settings.
|
||||
*/
|
||||
export interface ImportSettings {
|
||||
/**
|
||||
* A list of file extensions that will be parsed as modules and inspected for `export`s.
|
||||
*
|
||||
* @see [import/extensions](https://github.com/benmosher/eslint-plugin-import/blob/master/README.md#importextensions)
|
||||
*/
|
||||
'import/extensions'?: string[];
|
||||
|
||||
/**
|
||||
* If you require more granular extension definitions.
|
||||
*
|
||||
* @see [import/resolver](https://github.com/benmosher/eslint-plugin-import/blob/master/README.md#importresolver)
|
||||
*/
|
||||
'import/resolver'?: string | Record<string, unknown>;
|
||||
|
||||
/**
|
||||
* A list of regex strings that, if matched by a path, will not report the matching module if no `exports` are found.
|
||||
*
|
||||
* @see [import/ignore](https://github.com/benmosher/eslint-plugin-import/blob/master/README.md#importignore)
|
||||
*/
|
||||
'import/ignore'?: string[];
|
||||
|
||||
/**
|
||||
* An array of additional modules to consider as "core" modules--modules that should be considered resolved but have no path on the filesystem.
|
||||
*
|
||||
* @see [import/core-modules](https://github.com/benmosher/eslint-plugin-import/blob/master/README.md#importcore-modules)
|
||||
*/
|
||||
'import/core-modules'?: string[];
|
||||
|
||||
/**
|
||||
* An array of folders. Resolved modules only from those folders will be considered as "external".
|
||||
*
|
||||
* @default ["node_modules"]
|
||||
*
|
||||
* @see [import/external-module-folders](https://github.com/benmosher/eslint-plugin-import/blob/master/README.md#importexternal-module-folders)
|
||||
*/
|
||||
'import/external-module-folders'?: string[];
|
||||
|
||||
/**
|
||||
* A map from parsers to file extension arrays.
|
||||
*
|
||||
* @see [import/parsers](https://github.com/benmosher/eslint-plugin-import/blob/master/README.md#importparsers)
|
||||
*/
|
||||
'import/parsers'?: Partial<Record<Parser, string[]>>;
|
||||
|
||||
/**
|
||||
* Settings for cache behavior.
|
||||
*
|
||||
* @see [import/cache](https://github.com/benmosher/eslint-plugin-import/blob/master/README.md#importcache)
|
||||
*/
|
||||
'import/cache'?: { lifetime?: number } & Record<string, unknown>;
|
||||
|
||||
/**
|
||||
* A regex for packages should be treated as internal.
|
||||
*
|
||||
* Useful when you are utilizing a monorepo setup or developing a set of packages that depend on each other.
|
||||
*
|
||||
* @see [import/internal-regex](https://github.com/benmosher/eslint-plugin-import/blob/master/README.md#importinternal-regex)
|
||||
*/
|
||||
'import/internal-regex'?: string;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user