This commit is contained in:
Alex 2023-10-03 19:00:25 -04:00
parent 01f291af94
commit 8a07010f29
15 changed files with 741 additions and 716 deletions

View File

@ -1,18 +1,6 @@
#!/bin/bash #!/bin/bash
./src/build-local-rules.ts ./src/build-local-rules.ts
npx tsc ./src/local/index.ts --outdir ./dist/local --target ESNext --module CommonJS --esModuleInterop >/dev/null npx dts-bundle-generator "./src/index.ts" -o "./dist/index.d.ts" --project "./tsconfig.build.json" --no-check
npx tsc ./src/index.ts --outdir ./dist --declaration --target ESNext --module CommonJS --esModuleInterop >/dev/null
rm -r dist/redirect.*
./esbuild.ts ./esbuild.ts
sed -i '' '/import.*redirect.*;/d' dist/index.d.ts sed -i '' '/import.*redirect.*;/d' "dist/index.d.ts"
type() {
npx dts-bundle-generator "./packages/eslint-plugin-$1/$2" \
-o "./dist/$1/index.d.ts" \
--project "./packages/eslint-plugin-$1/tsconfig.json" \
--no-check
}
# type import src/index.js
# type jsx-a11y src/index.js
# type react index.js

24
dist/index.d.ts vendored
View File

@ -1,7 +1,17 @@
import type { ESLintConfig } from 'eslint-define-config'; // Generated by dts-bundle-generator v8.0.1
declare module 'eslint-define-config/src/rules/react/no-unknown-property.d.ts' {
interface NoUnknownPropertyOption { import { ESLintConfig } from 'eslint-define-config';
extends: ('next' | 'emotion')[];
} export declare const error = 'error';
} export declare const warn = 'warn';
export declare function extendConfig({ plugins, settings, rules, extends: _extends, overrides, ...rest }?: ESLintConfig): ESLintConfig; export declare const off = 'off';
export declare function extendConfig({
plugins,
settings,
rules,
extends: _extends,
overrides,
...rest
}?: ESLintConfig): ESLintConfig;
export {};

7
dist/package.json vendored
View File

@ -1,15 +1,14 @@
{ {
"name": "@aet/eslint-rules", "name": "@aet/eslint-rules",
"version": "0.0.1-beta.36", "version": "0.0.1-beta.37",
"license": "UNLICENSED", "license": "UNLICENSED",
"peerDependencies": { "peerDependencies": {
"esbin": "^0.0.2",
"typescript": "^5.2.2" "typescript": "^5.2.2"
}, },
"dependencies": { "dependencies": {
"@types/eslint": "^8.44.3", "@types/eslint": "^8.44.3",
"@typescript-eslint/eslint-plugin": "6.7.3", "@typescript-eslint/eslint-plugin": "6.7.4",
"@typescript-eslint/parser": "6.7.3", "@typescript-eslint/parser": "6.7.4",
"aria-query": "^5.3.0", "aria-query": "^5.3.0",
"axe-core": "4.8.2", "axe-core": "4.8.2",
"axobject-query": "^4.0.0", "axobject-query": "^4.0.0",

View File

@ -6,23 +6,23 @@
}, },
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"@babel/core": "^7.22.17", "@babel/core": "^7.23.0",
"@babel/plugin-transform-flow-strip-types": "^7.22.5", "@babel/plugin-transform-flow-strip-types": "^7.22.5",
"@babel/preset-env": "^7.22.15", "@babel/preset-env": "^7.22.20",
"@types/babel-plugin-macros": "^3.1.0", "@types/babel-plugin-macros": "^3.1.1",
"@types/babel__core": "^7.20.1", "@types/babel__core": "^7.20.2",
"@types/eslint": "^8.44.2", "@types/eslint": "^8.44.3",
"@types/estree": "^1.0.1", "@types/estree": "^1.0.2",
"@types/estree-jsx": "^1.0.0", "@types/estree-jsx": "^1.0.1",
"@types/lodash": "^4.14.198", "@types/lodash": "^4.14.199",
"@types/node": "^20.6.0", "@types/node": "^20.8.2",
"@typescript-eslint/types": "^6.7.0", "@typescript-eslint/types": "^6.7.4",
"babel-plugin-macros": "^3.1.0", "babel-plugin-macros": "^3.1.0",
"dts-bundle-generator": "^8.0.1", "dts-bundle-generator": "^8.0.1",
"esbin": "0.0.2", "esbin": "0.0.3",
"esbuild": "0.19.2", "esbuild": "0.19.4",
"esbuild-plugin-alias": "^0.2.1", "esbuild-plugin-alias": "^0.2.1",
"eslint": "8.49.0", "eslint": "8.50.0",
"eslint-config-prettier": "9.0.0", "eslint-config-prettier": "9.0.0",
"eslint-define-config": "^1.23.0", "eslint-define-config": "^1.23.0",
"fast-glob": "^3.3.1", "fast-glob": "^3.3.1",

View File

@ -1,5 +1,5 @@
diff --git a/package.json b/package.json diff --git a/package.json b/package.json
index 753be55..45bece4 100644 index 72587ff..74b7051 100644
--- a/package.json --- a/package.json
+++ b/package.json +++ b/package.json
@@ -62,8 +62,7 @@ @@ -62,8 +62,7 @@

1078
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@ set -e
pull() { pull() {
echo "🚛 Pulling $1" echo "🚛 Pulling $1"
(cd "packages/$1" && git config pull.rebase true && git config rebase.autoStash true && git pull) (cd "packages/$1" && git config pull.rebase true && git config rebase.autoStash true && git pull)
echo
} }
pull eslint-import-resolver-typescript pull eslint-import-resolver-typescript

View File

@ -1,5 +1,9 @@
import type { ESLintConfig } from 'eslint-define-config';
import './redirect'; import './redirect';
import type { ESLintConfig } from 'eslint-define-config';
import { typescriptRules } from './presets/typescript';
import { unicornRules } from './presets/unicorn';
import { eslintRules } from './presets/eslint';
import { reactRules } from './presets/react';
// @ts-expect-error // @ts-expect-error
const { name } = (0, require)('./package.json'); const { name } = (0, require)('./package.json');
@ -7,9 +11,9 @@ const unique = <T>(arr: T[]): T[] => [...new Set(arr)];
const ensureArray = <T>(value?: T | T[]): T[] => const ensureArray = <T>(value?: T | T[]): T[] =>
value == null ? [] : Array.isArray(value) ? value : [value]; value == null ? [] : Array.isArray(value) ? value : [value];
const error = 'error'; export const error = 'error';
const warn = 'warn'; export const warn = 'warn';
const off = 'off'; export const off = 'off';
declare module 'eslint-define-config/src/rules/react/no-unknown-property.d.ts' { declare module 'eslint-define-config/src/rules/react/no-unknown-property.d.ts' {
export interface NoUnknownPropertyOption { export interface NoUnknownPropertyOption {
@ -27,6 +31,7 @@ export function extendConfig({
}: ESLintConfig = {}): ESLintConfig { }: ESLintConfig = {}): ESLintConfig {
const hasReact = plugins?.includes('react'); const hasReact = plugins?.includes('react');
const hasReactRefresh = plugins?.includes('react-refresh'); const hasReactRefresh = plugins?.includes('react-refresh');
const hasUnicorn = plugins?.includes('unicorn');
const hasNext = ensureArray(_extends).some(name => name.includes(':@next/next')); const hasNext = ensureArray(_extends).some(name => name.includes(':@next/next'));
const result: ESLintConfig = { const result: ESLintConfig = {
@ -75,102 +80,21 @@ export function extendConfig({
...(overrides ?? []), ...(overrides ?? []),
], ],
rules: { rules: {
'no-duplicate-imports': error, ...eslintRules,
'no-restricted-imports': [ ...typescriptRules,
error,
{
paths: [
{
name: 'crypto',
importNames: ['webcrypto'],
message: 'Use global `crypto` instead',
},
],
},
],
'no-restricted-globals': [error, 'event', 'name', 'length'],
'@typescript-eslint/ban-ts-comment': [
error,
{
'ts-expect-error': 'allow-with-description',
'ts-check': false,
'ts-ignore': 'allow-with-description',
'ts-nocheck': 'allow-with-description',
},
],
'@typescript-eslint/consistent-type-imports': [
error,
{ disallowTypeAnnotations: false, fixStyle: 'inline-type-imports' },
],
'@typescript-eslint/ban-types': [error, { extendDefaults: true }],
'@typescript-eslint/no-empty-interface': [error, { allowSingleExtends: true }],
'@typescript-eslint/no-explicit-any': off,
'@typescript-eslint/no-extraneous-class': error,
'@typescript-eslint/no-misused-promises': [error, { checksVoidReturn: false }],
'@typescript-eslint/no-namespace': off,
'@typescript-eslint/no-unnecessary-type-assertion': error,
'@typescript-eslint/no-unsafe-argument': off,
'@typescript-eslint/no-unsafe-assignment': off,
'@typescript-eslint/no-unsafe-call': off,
'@typescript-eslint/no-unsafe-member-access': off,
'@typescript-eslint/no-unsafe-return': off,
'@typescript-eslint/no-unused-vars': [
error,
{ ignoreRestSiblings: true, varsIgnorePattern: '^_' },
],
'@typescript-eslint/no-use-before-define': off,
'@typescript-eslint/no-var-requires': off,
'@typescript-eslint/unbound-method': off,
'@typescript-eslint/triple-slash-reference': off,
'arrow-body-style': [error, 'as-needed'],
'class-methods-use-this': off,
complexity: [warn, { max: 100 }],
curly: [error, 'multi-line', 'consistent'],
eqeqeq: [error, 'smart'],
'no-async-promise-executor': off,
'no-case-declarations': off,
'no-console': warn,
'no-constant-condition': [error, { checkLoops: false }],
'no-debugger': warn,
'no-empty': [error, { allowEmptyCatch: true }],
'no-inner-declarations': off,
'no-lonely-if': error,
'no-template-curly-in-string': error,
'no-var': error,
'import/export': off, 'import/export': off,
'import/order': [error, { groups: ['builtin', 'external'] }], 'import/order': [error, { groups: ['builtin', 'external'] }],
'object-shorthand': [error, 'always', { ignoreConstructors: true }], ...(hasReact && {
'one-var': [error, { var: 'never', let: 'never' }], ...reactRules,
'prefer-arrow-callback': error,
'prefer-const': [error, { destructuring: 'all' }],
'prefer-destructuring': [
warn,
{ AssignmentExpression: { array: false, object: false } },
],
'prefer-object-spread': error,
'prefer-rest-params': warn,
'prefer-spread': warn,
'quote-props': [error, 'as-needed'],
'spaced-comment': [error, 'always', { markers: ['/', '#', '@'] }],
'sort-imports': [warn, { ignoreDeclarationSort: true }],
yoda: [error, 'never', { exceptRange: true }],
...(hasReact
? {
'react/display-name': off,
'react/no-children-prop': error,
'react/prop-types': off,
'react/react-in-jsx-scope': off,
'react/no-unknown-property': [ 'react/no-unknown-property': [
error, error,
{ extends: hasNext ? ['emotion', 'next'] : ['emotion'] }, { extends: hasNext ? ['emotion', 'next'] : ['emotion'] },
], ],
} }),
: {}), ...(hasReactRefresh && {
...(hasReactRefresh
? {
'react-refresh/only-export-components': [warn, { allowConstantExport: true }], 'react-refresh/only-export-components': [warn, { allowConstantExport: true }],
} }),
: {}), ...(hasUnicorn && unicornRules),
...rules, ...rules,
}, },
...rest, ...rest,

View File

@ -11,7 +11,15 @@ function tryRequire(candidates: string[]) {
} }
} }
tryRequire(['esbin/register', 'esbuild-register', 'ts-node/register/transpile-only']); // https://github.com/gulpjs/interpret
tryRequire([
'esbin/register',
'esbuild-register',
'ts-node/register/transpile-only',
'@swc/register',
'@babel/register',
'coffeescript/register',
]);
const folders = resolve(process.cwd(), 'eslint-local-rules'); const folders = resolve(process.cwd(), 'eslint-local-rules');
const files = fs.readdirSync(folders); const files = fs.readdirSync(folders);

49
src/presets/eslint.ts Normal file
View File

@ -0,0 +1,49 @@
import { error, warn, off } from '../index';
import { EslintRules } from 'eslint-define-config/src/rules/eslint';
export const eslintRules: Partial<EslintRules> = {
'arrow-body-style': [error, 'as-needed'],
'class-methods-use-this': off,
'no-async-promise-executor': off,
'no-case-declarations': off,
'no-console': warn,
'no-constant-condition': [error, { checkLoops: false }],
'no-debugger': warn,
'no-duplicate-imports': error,
'no-empty': [error, { allowEmptyCatch: true }],
'no-inner-declarations': off,
'no-lonely-if': error,
'no-restricted-globals': [error, 'event', 'name', 'length'],
'no-restricted-imports': [
error,
{
paths: [
{
name: 'crypto',
importNames: ['webcrypto'],
message: 'Use global `crypto` instead',
},
],
},
],
'no-template-curly-in-string': error,
'no-var': error,
'object-shorthand': [error, 'always', { ignoreConstructors: true }],
'one-var': [error, { var: 'never', let: 'never' }],
'prefer-arrow-callback': error,
'prefer-const': [error, { destructuring: 'all' }],
'prefer-destructuring': [
warn,
{ AssignmentExpression: { array: false, object: false } },
],
'prefer-object-spread': error,
'prefer-rest-params': warn,
'prefer-spread': warn,
'quote-props': [error, 'as-needed'],
'sort-imports': [warn, { ignoreDeclarationSort: true }],
'spaced-comment': [error, 'always', { markers: ['/', '#', '@'] }],
complexity: [warn, { max: 100 }],
curly: [error, 'multi-line', 'consistent'],
eqeqeq: [error, 'smart'],
yoda: [error, 'never', { exceptRange: true }],
};

9
src/presets/react.ts Normal file
View File

@ -0,0 +1,9 @@
import { error, off } from '../index';
import { ReactRules } from 'eslint-define-config/src/rules/react';
export const reactRules: Partial<ReactRules> = {
'react/display-name': off,
'react/no-children-prop': error,
'react/prop-types': off,
'react/react-in-jsx-scope': off,
};

38
src/presets/typescript.ts Normal file
View File

@ -0,0 +1,38 @@
import { error, off } from '../index';
import type { TypeScriptRules } from 'eslint-define-config/src/rules/typescript-eslint';
export const typescriptRules: Partial<TypeScriptRules> = {
'@typescript-eslint/ban-ts-comment': [
error,
{
'ts-expect-error': 'allow-with-description',
'ts-check': false,
'ts-ignore': 'allow-with-description',
'ts-nocheck': 'allow-with-description',
},
],
'@typescript-eslint/ban-types': [error, { extendDefaults: true }],
'@typescript-eslint/consistent-type-imports': [
error,
{ disallowTypeAnnotations: false, fixStyle: 'inline-type-imports' },
],
'@typescript-eslint/no-empty-interface': [error, { allowSingleExtends: true }],
'@typescript-eslint/no-explicit-any': off,
'@typescript-eslint/no-extraneous-class': error,
'@typescript-eslint/no-misused-promises': [error, { checksVoidReturn: false }],
'@typescript-eslint/no-namespace': off,
'@typescript-eslint/no-unnecessary-type-assertion': error,
'@typescript-eslint/no-unsafe-argument': off,
'@typescript-eslint/no-unsafe-assignment': off,
'@typescript-eslint/no-unsafe-call': off,
'@typescript-eslint/no-unsafe-member-access': off,
'@typescript-eslint/no-unsafe-return': off,
'@typescript-eslint/no-unused-vars': [
error,
{ ignoreRestSiblings: true, varsIgnorePattern: '^_' },
],
'@typescript-eslint/no-use-before-define': off,
'@typescript-eslint/no-var-requires': off,
'@typescript-eslint/triple-slash-reference': off,
'@typescript-eslint/unbound-method': off,
};

68
src/presets/unicorn.ts Normal file
View File

@ -0,0 +1,68 @@
import { error, warn } from '../index';
import { UnicornRules } from 'eslint-define-config/src/rules/unicorn';
const suggest = (suggest: string) => ({ suggest, fix: false });
// https://github.com/sindresorhus/eslint-plugin-unicorn/tree/28e7498ad06679bb92343db53bb40a7b5ba2990a
export const unicornRules: Partial<UnicornRules> = {
'unicorn/better-regex': error,
'unicorn/consistent-function-scoping': warn,
'unicorn/escape-case': error,
'unicorn/no-array-for-each': warn,
'unicorn/no-array-method-this-argument': error,
'unicorn/no-array-push-push': warn,
'unicorn/no-console-spaces': warn,
'unicorn/no-for-loop': warn,
'unicorn/no-instanceof-array': error,
'unicorn/no-lonely-if': warn,
'unicorn/no-static-only-class': error,
'unicorn/no-typeof-undefined': error,
// 'unicorn/no-unused-properties': warn,
'unicorn/no-useless-fallback-in-spread': error,
'unicorn/no-useless-promise-resolve-reject': error,
'unicorn/no-useless-spread': error,
'unicorn/no-useless-switch-case': error,
'unicorn/number-literal-case': error,
'unicorn/prefer-array-find': error,
'unicorn/prefer-array-flat-map': error,
'unicorn/prefer-array-some': error,
'unicorn/prefer-at': error,
'unicorn/prefer-blob-reading-methods': error,
'unicorn/prefer-date-now': error,
'unicorn/prefer-default-parameters': warn,
'unicorn/prefer-dom-node-dataset': error,
'unicorn/prefer-dom-node-remove': error,
'unicorn/prefer-export-from': [error, { ignoreUsedVariables: false }],
'unicorn/prefer-includes': error,
'unicorn/prefer-keyboard-event-key': warn,
'unicorn/prefer-logical-operator-over-ternary': warn,
'unicorn/prefer-math-trunc': error,
'unicorn/prefer-modern-math-apis': error,
'unicorn/prefer-negative-index': error,
'unicorn/prefer-node-protocol': error,
'unicorn/prefer-object-from-entries': error,
'unicorn/prefer-optional-catch-binding': error,
'unicorn/prefer-reflect-apply': error,
'unicorn/prefer-regexp-test': error,
'unicorn/prefer-set-has': warn,
'unicorn/prefer-string-slice': error,
'unicorn/prefer-string-starts-ends-with': warn,
'unicorn/prefer-string-trim-start-end': error,
'unicorn/prefer-ternary': warn,
'unicorn/string-content': [
warn,
{
patterns: {
'->': suggest('→'),
'=>': suggest('⇒'),
'<-': suggest('←'),
'<=': suggest('≤'),
'>=': suggest('≥'),
'!=': suggest('≠'),
'<=>': suggest('⇔'),
'...': suggest('…'),
},
},
],
'unicorn/template-indent': warn,
};

7
tsconfig.build.json Normal file
View File

@ -0,0 +1,7 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"skipLibCheck": true
}
}

View File

@ -3,12 +3,12 @@
"allowJs": true, "allowJs": true,
"allowArbitraryExtensions": true, "allowArbitraryExtensions": true,
"declaration": true, "declaration": true,
"emitDeclarationOnly": true,
"esModuleInterop": true, "esModuleInterop": true,
"experimentalDecorators": true, "experimentalDecorators": true,
"jsx": "react-jsx", "jsx": "react-jsx",
"module": "commonjs", "module": "commonjs",
"moduleResolution": "node", "moduleResolution": "node",
"noEmit": true,
"noImplicitOverride": true, "noImplicitOverride": true,
"noUnusedLocals": true, "noUnusedLocals": true,
"noUnusedParameters": true, "noUnusedParameters": true,