Skip to content

Commit

Permalink
🐛 fix(formatting): add more stricter ruleser
Browse files Browse the repository at this point in the history
Signed-off-by: Pauline <git@ethanlibs.co>
  • Loading branch information
pauliesnug committed Nov 20, 2024
1 parent b2bfbe6 commit 7f8852c
Show file tree
Hide file tree
Showing 47 changed files with 815 additions and 1,236 deletions.
6 changes: 1 addition & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"type": "module",
"version": "4.4.1",
"private": true,
"packageManager": "pnpm@9.13.2",
"packageManager": "pnpm@9.14.1",
"engineStrict": true,
"author": "@flowr",
"contributors": [
Expand Down Expand Up @@ -50,10 +50,6 @@
"devDependencies": {
"@arethetypeswrong/cli": "^0.17.0",
"@flowr/eslint": "workspace:^",
"@microsoft/api-extractor": "^7.47.11",
"@microsoft/api-extractor-model": "^7.29.8",
"@microsoft/tsdoc": "^0.15.0",
"@microsoft/tsdoc-config": "^0.17.0",
"@turbo/gen": "^2.3.0",
"@types/jsdom": "^21.1.7",
"@types/node": "^22.9.0",
Expand Down
3 changes: 3 additions & 0 deletions packages/eslint-plugin/src/rules/consistent-list-newline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ export default createEslintRule<Options, MessageIds>({
const endLoc = context.sourceCode.getLocFromIndex(endRange);

const lastItem = items[items.length - 1];
// eslint-disable-next-line ts/no-unnecessary-condition -- side effects
if (mode === 'newline' && endLoc.line === lastLine) {
context.report({
data: {
Expand All @@ -149,6 +150,7 @@ export default createEslintRule<Options, MessageIds>({
node: lastItem,
});
}
// eslint-disable-next-line ts/no-unnecessary-condition -- side effects
else if (mode === 'inline' && endLoc.line !== lastLine) {
// if there is only one multiline item, we allow the closing bracket to be on the a different line
if (items.length === 1 && items[0].loc.start.line !== items[1]?.loc.start.line)
Expand Down Expand Up @@ -274,4 +276,5 @@ export default createEslintRule<Options, MessageIds>({
name: RULE_NAME,
});

// eslint-disable-next-line ts/no-unnecessary-type-parameters -- type testing
function exportType<A, _B extends A>(): void { }
5 changes: 3 additions & 2 deletions packages/eslint-plugin/src/rules/file-header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ function makeComment(text: string, syntax: CommentSyntax, decor: DecorSyntax): s

function matchHeader(src: string, headers: string[], templates: TemplatesSyntax): boolean {
for (const header of headers) {
const body = escapeRegex(header)
.replace(/\\\{(\w+)\\\}/g, (m, k) => templates[k]?.[0] ?? m);
// eslint-disable-next-line ts/no-unnecessary-condition -- weak types
const body = escapeRegex(header).replace(/\\\{(\w+)\\\}/g, (m, k) => templates[k]?.[0] ?? m);
if (new RegExp(`^${body}$`).test(src))
return true;
}
Expand All @@ -200,6 +200,7 @@ function matchHeader(src: string, headers: string[], templates: TemplatesSyntax)
}

function makeHeader(headers: string[], templates: TemplatesSyntax): string {
// eslint-disable-next-line ts/no-unnecessary-condition -- weak types
return headers[0].replace(/\{(\w+)\}/g, (m, k) => templates[k]?.[1] ?? m);
}

Expand Down
2 changes: 0 additions & 2 deletions packages/eslint-plugin/src/rules/if-newline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ export type Options = [];
export default createEslintRule<Options, MessageIds>({
create: context => ({
IfStatement: (node) => {
if (!node.consequent)
return;
if (node.consequent.type === 'BlockStatement')
return;
if (node.test.loc.end.line === node.consequent.loc.start.line)
Expand Down
4 changes: 2 additions & 2 deletions packages/eslint-plugin/src/rules/indent-unindent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ const defaultOptions: Options = [{

export default createEslintRule<Options, MessageIds>({
create: (context) => {
const { tags = ['$', 'unindent', 'unIndent'] } = context.options[0] ?? {};
const { tags = ['$', 'unindent', 'unIndent'] } = context.options[0];
const tagSet = new Set(tags);

return {
TaggedTemplateExpression: (node) => {
const id = node.tag;
if (!id || id.type !== 'Identifier')
if (id.type !== 'Identifier')
return;
if (!tagSet.has(id.name))
return;
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/src/rules/no-discard-result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ function hasResultLikeReturnType(
const returnType = unwrapPotentialPromise(checker, nodeMap);
const resultType = getResultType(service, checker);

if (!returnType || !returnType.aliasSymbol || !resultType?.aliasSymbol)
if (!returnType.aliasSymbol || !resultType?.aliasSymbol)
return false;

// hacky bit of reflection logic until type relationship api https://github.com/microsoft/TypeScript/issues/9879
Expand Down
4 changes: 2 additions & 2 deletions packages/eslint-plugin/src/rules/no-only-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ export type Options = [{
function getCallPath(node: TSESTree.Node, path: string[] = []): string[] {
if (node.type === 'Identifier')
return [node.name, ...path];
if (node.type === 'MemberExpression' && node.object)
if (node.type === 'MemberExpression')
return getCallPath(node.object, [(node.property as TSESTree.Identifier).name, ...path]);
if (node.type === 'CallExpression' && node.callee)
if (node.type === 'CallExpression')
return getCallPath(node.callee, path);

return path;
Expand Down
4 changes: 2 additions & 2 deletions packages/eslint-plugin/src/rules/top-level-function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ export default createEslintRule<Options, MessageIds>({

if (declaration.init?.type !== 'ArrowFunctionExpression')
return;
if (declaration.id?.type !== 'Identifier')
if (declaration.id.type !== 'Identifier')
return;
if (declaration.id.typeAnnotation)
return;
if (
declaration.init.body.type !== 'BlockStatement'
&& declaration.id?.loc.start.line === declaration.init?.body.loc.end.line
&& declaration.id.loc.start.line === declaration.init.body.loc.end.line
)
return;

Expand Down
8 changes: 4 additions & 4 deletions packages/eslint/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
"@eslint-community/eslint-plugin-eslint-comments": "^4.4.1",
"@eslint/compat": "^1.2.3",
"@eslint/markdown": "^6.2.1",
"@stylistic/eslint-plugin": "^2.10.1",
"@stylistic/eslint-plugin": "^2.11.0",
"@typescript-eslint/eslint-plugin": "^8.15.0",
"@typescript-eslint/parser": "^8.15.0",
"@vitest/eslint-plugin": "^1.1.10",
Expand All @@ -162,17 +162,17 @@
"eslint-plugin-jsdoc": "^50.5.0",
"eslint-plugin-jsonc": "^2.18.2",
"eslint-plugin-n": "^17.13.2",
"eslint-plugin-perfectionist": "^3.9.1",
"eslint-plugin-perfectionist": "^4.0.1",
"eslint-plugin-petal": "workspace:^",
"eslint-plugin-regexp": "^2.7.0",
"eslint-plugin-toml": "^0.11.1",
"eslint-plugin-unicorn": "^56.0.0",
"eslint-plugin-unicorn": "^56.0.1",
"eslint-plugin-unused-imports": "^4.1.4",
"eslint-plugin-yml": "^1.15.0",
"find-up-simple": "^1.0.0",
"globals": "^15.12.0",
"jsonc-eslint-parser": "^2.4.0",
"local-pkg": "^0.5.0",
"local-pkg": "^0.5.1",
"toml-eslint-parser": "^0.10.0",
"yaml-eslint-parser": "^1.2.3"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint/scripts/typegen.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { writeFile } from 'node:fs/promises';
import { builtinRules } from 'eslint/use-at-your-own-risk';
import { flatConfigsToRulesDTS } from 'eslint-typegen/core';
import { builtinRules } from 'eslint/use-at-your-own-risk';
import {
astro,
comments,
Expand Down
16 changes: 8 additions & 8 deletions packages/eslint/src/configs/gitignore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,31 +38,31 @@ function relativeMinimatch(pattern: string, relativePath: string, cwd: string):
if (new Set(['', '.', '/']).has(relativePath))
return pattern;

const negated = pattern.startsWith('!') ? '!' : ':';
const minimatch = { clearPattern: negated ? pattern.slice(1) : pattern };
const negated = pattern.startsWith('!') ? '!' : '';
const minimatch = { cleanPattern: negated ? pattern.slice(1) : pattern };

if (!relativePath.endsWith('/'))
relativePath = `${relativePath}/`;

const parent = relativePath.startsWith('..');

if (!parent)
return `${negated}${relativePath}${minimatch.clearPattern}`;
return `${negated}${relativePath}${minimatch.cleanPattern}`;

if (!relativePath.match(/^(?:\.\.\/)+$/))
throw new Error('the ignored file location should be a parent or child directory.');

if (minimatch.clearPattern.startsWith('**'))
if (minimatch.cleanPattern.startsWith('**'))
return pattern;

const parents = relative(resolve(cwd, relativePath), cwd).split(/[/\\]/);
while (parents.length && minimatch.clearPattern.startsWith(`${parents[0]}/`)) {
minimatch.clearPattern = minimatch.clearPattern.slice(parents[0].length + 1);
while (parents.length && minimatch.cleanPattern.startsWith(`${parents[0]}/`)) {
minimatch.cleanPattern = minimatch.cleanPattern.slice(parents[0].length + 1);
parents.shift();
}

if (minimatch.clearPattern.startsWith('**') || parents.length === 0)
return `${negated}${minimatch.clearPattern}`;
if (minimatch.cleanPattern.startsWith('**') || parents.length === 0)
return `${negated}${minimatch.cleanPattern}`;

return null;
}
22 changes: 11 additions & 11 deletions packages/eslint/src/configs/perfectionist.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
import type { TypedFlatConfigItem } from '../types/index.ts';
import { interopDefault } from '../utils.ts';

type SortConfig = ['error', {
interface SortConfig {
type?: ('alphabetical' | 'natural' | 'line-length');
order?: ('asc' | 'desc');
}];

}

const sortConfig: SortConfig = { order: 'asc', type: 'natural' };

/**
* Perfectionist plugin for props and items sorting.
*
* @see https://github.com/azat-io/eslint-plugin-perfectionist
*/
export async function perfectionist(): Promise<TypedFlatConfigItem[]> {
const sortConfig: SortConfig = ['error', { order: 'asc', type: 'natural' }];

return [
{
name: 'petal/perfectionist/setup',
plugins: {
perfectionist: await interopDefault(import('eslint-plugin-perfectionist')),
},
rules: {
'perfectionist/sort-array-includes': sortConfig,
'perfectionist/sort-exports': sortConfig,
'perfectionist/sort-array-includes': ['error', sortConfig],
'perfectionist/sort-exports': ['error', sortConfig],
'perfectionist/sort-imports': ['error', {
...sortConfig,
groups: [
'type',
['parent-type', 'sibling-type', 'index-type'],
Expand All @@ -37,12 +39,10 @@ export async function perfectionist(): Promise<TypedFlatConfigItem[]> {
'unknown',
],
newlinesBetween: 'ignore',
order: 'asc',
type: 'natural',
}],
'perfectionist/sort-named-exports': sortConfig,
'perfectionist/sort-named-imports': sortConfig,
'perfectionist/sort-sets': sortConfig,
'perfectionist/sort-named-exports': ['error', sortConfig],
'perfectionist/sort-named-imports': ['error', sortConfig],
'perfectionist/sort-sets': ['error', sortConfig],
},
},
];
Expand Down
8 changes: 8 additions & 0 deletions packages/eslint/src/configs/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export async function typescript(options: OptionsTypeScript = {}): Promise<Typed
'ts-ignore': false,
'ts-nocheck': false,
}],
'ts/no-unnecessary-parameter-property-assignment': 'error',
'ts/ban-tslint-comment': 'error',
'ts/class-literal-property-style': ['error', 'fields'],
'ts/class-methods-use-this': ['error', { ignoreClassesThatImplementAnInterface: true, ignoreOverrideMethods: false }],
Expand Down Expand Up @@ -111,6 +112,7 @@ export async function typescript(options: OptionsTypeScript = {}): Promise<Typed
allowTernary: true,
}],
'ts/no-unused-vars': 'off',
'ts/no-useless-empty-export': 'error',
'ts/no-use-before-define': ['error', { classes: false, functions: false, variables: true }],
'ts/no-useless-constructor': 'off',
'ts/no-wrapper-object-types': 'error',
Expand Down Expand Up @@ -165,8 +167,14 @@ export async function typescript(options: OptionsTypeScript = {}): Promise<Typed
'ts/no-unsafe-argument': 'error',
'ts/no-unsafe-assignment': 'error',
'ts/no-unsafe-call': 'error',
'ts/no-unnecessary-type-parameters': 'error',
'ts/no-unsafe-member-access': 'error',
'ts/no-unnecessary-type-arguments': 'error',
'ts/no-unnecessary-template-expression': 'error',
'ts/no-unnecessary-qualifier': 'error',
'ts/no-unnecessary-condition': ['error', { allowConstantLoopConditions: true }],
'ts/no-unsafe-return': 'error',
'ts/no-unnecessary-boolean-literal-compare': 'error',
'ts/related-getter-setter-pairs': 'error',
'ts/prefer-readonly': 'off',
'ts/promise-function-async': 'error',
Expand Down
5 changes: 4 additions & 1 deletion packages/eslint/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ export const isPackageInScope = (name: string): boolean => isPackageExists(name,
* ```
*/
export async function ensurePackages(packages: Array<string | undefined>): Promise<void> {
if (process.env.CI || process.stdout.isTTY === false || isCwdInScope === false)
if (process.env.CI || !process.stdout.isTTY || !isCwdInScope)
return;

const nonExistingPackages = packages.filter(i => i && !isPackageInScope(i)) as string[];
Expand All @@ -201,6 +201,7 @@ export function resolveSubOptions<Key extends keyof OptionsConfig>(options: Opti
return typeof options[key] === 'boolean' ? {} as any : options[key] || {};
}

// eslint-disable-next-line ts/no-unnecessary-type-parameters -- weird types
export function getOverrides<Key extends keyof OptionsConfig>(options: OptionsConfig, key: Key): Partial<Linter.RulesRecord & Rules> {
const sub = resolveSubOptions(options, key);
return { ...'overrides' in sub ? sub.overrides : {} };
Expand All @@ -212,6 +213,7 @@ export function isInEditorEnv(): boolean {
if (isInHook())
return false;

// eslint-disable-next-line ts/no-unnecessary-condition -- codeflow
return !!(false
|| process.env.VSCODE_PID
|| process.env.VSCODE_CWD
Expand All @@ -222,6 +224,7 @@ export function isInEditorEnv(): boolean {
}

export function isInHook(): boolean {
// eslint-disable-next-line ts/no-unnecessary-condition -- codeflow
return !!(false
|| process.env.GIT_PARAMS
|| process.env.VSCODE_GIT_COMMAND
Expand Down
7 changes: 3 additions & 4 deletions packages/eslint/tests/fixtures.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,15 @@ function runWithConfig(name: TemplateStringsArray) {
const from = resolve(fixturesDir, 'input');
const output = resolve(fixturesDir, 'output', name[0]);
const target = resolve(outputDir, name[0]);
const configString = JSON.stringify(configs);
const jsonString = JSON.stringify(items) as any ?? [];

await fs.copy(from, target, { filter: src => !src.includes('node_modules') });
await fs.writeFile(join(target, 'eslint.config.js'), `
// @eslint-disable
import { defineConfig } from '@flowr/eslint';
export default defineConfig(
${JSON.stringify(configs)},
...${JSON.stringify(items) ?? []},
);
export default defineConfig(${configString}, ...${jsonString});
`, 'utf-8');

if (process.platform === 'win32')
Expand Down
1 change: 1 addition & 0 deletions packages/fetch/src/lib/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ function shouldJsonStringify(value: unknown): boolean {

if (value === null)
return true;
// eslint-disable-next-line ts/no-unnecessary-condition -- Function can be undefined
if (value.constructor === undefined)
return true;
if (value.constructor === Object)
Expand Down
2 changes: 1 addition & 1 deletion packages/loader/src/lib/structures/Store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ export class Store<T extends Piece, StoreName extends StoreRegistryKey = StoreRe
Store.logger?.(`[STORE => ${this.name}] [INSERT] Loaded new piece '${piece.name}'.`);

// If the onLoad disabled the piece, call unload and return it:
// eslint-disable-next-line ts/no-unnecessary-condition -- side effects from onLoad
if (!piece.enabled) {
// Unload piece:
this.strategy.onUnload(this, piece);
await piece.onUnload();
Store.logger?.(`[STORE => ${this.name}] [INSERT] Unloaded new piece '${piece.name}' due to 'enabled' being 'false'.`);
Expand Down
Loading

0 comments on commit 7f8852c

Please sign in to comment.