From 2e7a9e932481be677f67740635291ef75af9a5cc Mon Sep 17 00:00:00 2001 From: YaroShkvorets Date: Sat, 7 Dec 2024 13:48:45 -0500 Subject: [PATCH] migrate eslint, fix lint warnings --- .eslintrc.cjs | 57 ---------------------- eslint.config.js | 66 ++++++++++++++++++++++++++ package.json | 6 ++- pnpm-lock.yaml | 3 ++ website/package.json | 2 +- website/src/components/Dropzone.tsx | 2 +- website/src/components/ui/form.tsx | 2 +- website/src/components/ui/input.tsx | 2 +- website/src/components/ui/textarea.tsx | 2 +- website/src/components/ui/toaster.tsx | 2 +- website/src/components/ui/use-toast.ts | 28 +++++------ website/src/routes/publish.lazy.tsx | 37 ++++++++------- website/tailwind.config.js | 8 ++-- website/vite.config.ts | 2 +- 14 files changed, 117 insertions(+), 102 deletions(-) delete mode 100644 .eslintrc.cjs create mode 100644 eslint.config.js diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index bfecb167e..000000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,57 +0,0 @@ -module.exports = { - extends: ['@theguild'], - ignorePatterns: [ - 'node_modules', - 'dist', - 'build', - 'generated', - 'packages/cli/tests/cli/init', - 'packages/cli/tests/cli/validation', - 'packages/ts/test/', - 'examples', - 'vitest.config.ts', - ], - rules: { - // not necessary here, we dont build with bob - 'import/extensions': 'off', - // pushing to array multiple times is not a big deal - 'unicorn/no-array-push-push': 'off', - // TODO: remove default exports, breaking change? - 'import/no-default-export': 'off', - // TODO: remove once we get rid of all anys - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/ban-types': 'off', - // AssemblyScript `===` is a reference equality check, not a value equality check. We are trying to do a value check. Learn more: https://github.com/AssemblyScript/assemblyscript/issues/621#issuecomment-497973428 - eqeqeq: 'off', - '@typescript-eslint/no-unused-vars': 'off', - }, - overrides: [ - { - files: ['packages/ts/**'], - rules: { - // TODO: want to avoid any structural change so fix it later - '@typescript-eslint/no-namespace': 'off', - // Some operator depend on the implementation of others, prevent recursion - 'sonarjs/no-inverted-boolean-check': 'off', - 'no-loss-of-precision': 'warn', - // AssemblyScript types are different from TS and in cases we want to use what TS may think we should not, - }, - }, - { - files: ['packages/cli/**'], - rules: { - 'no-restricted-imports': [ - 'error', - { - patterns: [ - { - group: ['@whatwg-node/fetch'], - message: 'Please use `fetch` from `./packages/cli/src/fetch.ts`.', - }, - ], - }, - ], - }, - }, - ], -}; diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 000000000..6439beff4 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,66 @@ +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { FlatCompat } from '@eslint/eslintrc'; +import js from '@eslint/js'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}); + +export default [ + { + ignores: [ + '**/node_modules', + '**/dist', + '**/build', + '**/generated', + 'packages/cli/tests/cli/init', + 'packages/cli/tests/cli/validation', + 'packages/ts/test/', + '**/examples', + '**/vitest.config.ts', + ], + }, + ...compat.extends('@theguild'), + { + rules: { + 'import/extensions': 'off', + 'unicorn/no-array-push-push': 'off', + 'import/no-default-export': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/ban-types': 'off', + eqeqeq: 'off', + '@typescript-eslint/no-unused-vars': 'off', + }, + }, + { + files: ['packages/ts/**'], + + rules: { + '@typescript-eslint/no-namespace': 'off', + 'sonarjs/no-inverted-boolean-check': 'off', + 'no-loss-of-precision': 'warn', + }, + }, + { + files: ['packages/cli/**'], + + rules: { + 'no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['@whatwg-node/fetch'], + message: 'Please use `fetch` from `./packages/cli/src/fetch.ts`.', + }, + ], + }, + ], + }, + }, +]; diff --git a/package.json b/package.json index 42ceabc8a..b3fbf192d 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "name": "graphprotocol-tools-monorepo", + "type": "module", "repository": { "type": "git", "url": "git+https://github.com/graphprotocol/graph-cli" @@ -17,8 +18,8 @@ "scripts": { "build": "pnpm --filter=@graphprotocol/graph-* build", "lint": "pnpm lint:prettier && pnpm lint:eslint", - "lint:eslint": "ESLINT_USE_FLAT_CONFIG=false eslint .", - "lint:eslint:fix": "ESLINT_USE_FLAT_CONFIG=false eslint . --fix", + "lint:eslint": "eslint .", + "lint:eslint:fix": "eslint . --fix", "lint:fix": "pnpm lint:prettier:fix && pnpm lint:eslint:fix", "lint:prettier": "prettier -c .", "lint:prettier:fix": "prettier . --write", @@ -30,6 +31,7 @@ "devDependencies": { "@changesets/changelog-github": "^0.5.0", "@changesets/cli": "^2.27.10", + "@eslint/js": "^9.16.0", "@theguild/eslint-config": "0.13.1", "@theguild/prettier-config": "3.0.0", "@types/node": "^22.10.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a367de563..9db77d92c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@changesets/cli': specifier: ^2.27.10 version: 2.27.10 + '@eslint/js': + specifier: ^9.16.0 + version: 9.16.0 '@theguild/eslint-config': specifier: 0.13.1 version: 0.13.1(eslint@9.16.0(jiti@2.4.1))(typescript@5.6.2) diff --git a/website/package.json b/website/package.json index 4301e65de..647c81ab5 100644 --- a/website/package.json +++ b/website/package.json @@ -7,7 +7,7 @@ "build": "tsc && vite build", "clean": "rimraf ./dist", "dev": "vite", - "lint": "ESLINT_USE_FLAT_CONFIG=false eslint . --report-unused-disable-directives", + "lint": "eslint . --report-unused-disable-directives", "prebuild": "tsr generate", "preview": "vite preview" }, diff --git a/website/src/components/Dropzone.tsx b/website/src/components/Dropzone.tsx index b4fe2bc76..3f2cb16ed 100644 --- a/website/src/components/Dropzone.tsx +++ b/website/src/components/Dropzone.tsx @@ -13,7 +13,7 @@ const ACCEPTED_IMAGE_TYPES = { }; // Limit avatar images to 1mb -const MAX_IMAGE_SIZE = 1000000; +const MAX_IMAGE_SIZE = 1_000_000; const BOX_SIZE = 152; diff --git a/website/src/components/ui/form.tsx b/website/src/components/ui/form.tsx index 04611d0bd..a0088060e 100644 --- a/website/src/components/ui/form.tsx +++ b/website/src/components/ui/form.tsx @@ -105,7 +105,7 @@ const FormControl = React.forwardRef< diff --git a/website/src/components/ui/input.tsx b/website/src/components/ui/input.tsx index 4e7503a09..c3a45c14c 100644 --- a/website/src/components/ui/input.tsx +++ b/website/src/components/ui/input.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { cn } from '@/lib/utils'; -export interface InputProps extends React.InputHTMLAttributes {} +type InputProps = React.InputHTMLAttributes; const Input = React.forwardRef( ({ className, type, ...props }, ref) => { diff --git a/website/src/components/ui/textarea.tsx b/website/src/components/ui/textarea.tsx index 182d3a948..444586f42 100644 --- a/website/src/components/ui/textarea.tsx +++ b/website/src/components/ui/textarea.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { cn } from '@/lib/utils'; -export interface TextareaProps extends React.TextareaHTMLAttributes {} +type TextareaProps = React.TextareaHTMLAttributes; const Textarea = React.forwardRef( ({ className, ...props }, ref) => { diff --git a/website/src/components/ui/toaster.tsx b/website/src/components/ui/toaster.tsx index 1b4e56131..04eee4be6 100644 --- a/website/src/components/ui/toaster.tsx +++ b/website/src/components/ui/toaster.tsx @@ -13,7 +13,7 @@ export function Toaster() { return ( - {toasts.map(function ({ id, title, description, action, ...props }) { + {toasts.map(({ id, title, description, action, ...props }) => { return (
diff --git a/website/src/components/ui/use-toast.ts b/website/src/components/ui/use-toast.ts index e43f67574..57e33d947 100644 --- a/website/src/components/ui/use-toast.ts +++ b/website/src/components/ui/use-toast.ts @@ -3,7 +3,7 @@ import * as React from 'react'; import type { ToastActionElement, ToastProps } from '@/components/ui/toast'; const TOAST_LIMIT = 1; -const TOAST_REMOVE_DELAY = 1000000; +const TOAST_REMOVE_DELAY = 1_000_000; type ToasterToast = ToastProps & { id: string; @@ -12,12 +12,12 @@ type ToasterToast = ToastProps & { action?: ToastActionElement; }; -const actionTypes = { - ADD_TOAST: 'ADD_TOAST', - UPDATE_TOAST: 'UPDATE_TOAST', - DISMISS_TOAST: 'DISMISS_TOAST', - REMOVE_TOAST: 'REMOVE_TOAST', -} as const; +type ActionType = { + ADD_TOAST: 'ADD_TOAST'; + UPDATE_TOAST: 'UPDATE_TOAST'; + DISMISS_TOAST: 'DISMISS_TOAST'; + REMOVE_TOAST: 'REMOVE_TOAST'; +}; let count = 0; @@ -26,8 +26,6 @@ function genId() { return count.toString(); } -type ActionType = typeof actionTypes; - type Action = | { type: ActionType['ADD_TOAST']; @@ -61,7 +59,7 @@ const addToRemoveQueue = (toastId: string) => { toastTimeouts.delete(toastId); dispatch({ type: 'REMOVE_TOAST', - toastId: toastId, + toastId, }); }, TOAST_REMOVE_DELAY); @@ -90,9 +88,9 @@ export const reducer = (state: State, action: Action): State => { if (toastId) { addToRemoveQueue(toastId); } else { - state.toasts.forEach(toast => { + for (const toast of state.toasts) { addToRemoveQueue(toast.id); - }); + } } return { @@ -127,9 +125,9 @@ let memoryState: State = { toasts: [] }; function dispatch(action: Action) { memoryState = reducer(memoryState, action); - listeners.forEach(listener => { + for (const listener of listeners) { listener(memoryState); - }); + } } type Toast = Omit; @@ -157,7 +155,7 @@ function toast({ ...props }: Toast) { }); return { - id: id, + id, dismiss, update, }; diff --git a/website/src/routes/publish.lazy.tsx b/website/src/routes/publish.lazy.tsx index a8c9b2aa6..b297bd6b0 100644 --- a/website/src/routes/publish.lazy.tsx +++ b/website/src/routes/publish.lazy.tsx @@ -6,8 +6,8 @@ import { Address } from 'viem'; import { useAccount, useSwitchChain, useWriteContract } from 'wagmi'; import yaml from 'yaml'; import { z } from 'zod'; -import { SubgraphImageDropZone } from '@/components/Dropzone'; -import { Editor } from '@/components/Editor'; +import { SubgraphImageDropZone } from '@/components/dropzone'; +import { Editor } from '@/components/editor'; import { Button } from '@/components/ui/button'; import { Form, @@ -38,18 +38,18 @@ import { ipfsHexHash } from '@/lib/utils'; import { zodResolver } from '@hookform/resolvers/zod'; import { useQuery } from '@tanstack/react-query'; import { createLazyFileRoute } from '@tanstack/react-router'; -import { L2GNSABI } from '../abis/L2GNS'; +import { L2GNSABI } from '../abis/l2gns'; import addresses from '../addresses.json'; const SUPPORTED_CHAIN = { 'arbitrum-one': { - chainId: 42161, - contracts: addresses[42161], + chainId: 42_161, + contracts: addresses[42_161], subgraph: NETWORK_SUBGRAPH_MAINNET, }, 'arbitrum-sepolia': { - chainId: 421614, - contracts: addresses[421614], + chainId: 421_614, + contracts: addresses[421_614], subgraph: NETWORK_SUBGRAPH_SEPOLIA, }, } as const; @@ -60,9 +60,9 @@ const getChainInfo = (chain: keyof typeof SUPPORTED_CHAIN) => { const publishToCopy = (chain: ReturnType['chainId']) => { switch (chain) { - case 42161: + case 42_161: return 'The Graph Network'; - case 421614: + case 421_614: return 'The Graph Testnet (not meant for production workload)'; } }; @@ -390,16 +390,17 @@ function DeploySubgraph({ toast({ description: 'You are all set! You can go back to the CLI and close this window', }); - } catch (err) { + } catch (_) { const e = contractError; - if (e?.name === 'ContractFunctionExecutionError') { - if (e.cause.name === 'ContractFunctionRevertedError') { - toast({ - description: e.cause.message, - variant: 'destructive', - }); - return; - } + if ( + e?.name === 'ContractFunctionExecutionError' && + e.cause.name === 'ContractFunctionRevertedError' + ) { + toast({ + description: e.cause.message, + variant: 'destructive', + }); + return; } toast({ diff --git a/website/tailwind.config.js b/website/tailwind.config.js index 05a774823..97520eb35 100644 --- a/website/tailwind.config.js +++ b/website/tailwind.config.js @@ -1,6 +1,8 @@ -/* eslint-disable no-undef */ /** @type {import('tailwindcss').Config} */ -module.exports = { + +import animate from 'tailwindcss-animate'; + +export default { darkMode: ['class'], content: [ './pages/**/*.{ts,tsx}', @@ -74,5 +76,5 @@ module.exports = { }, }, }, - plugins: [require('tailwindcss-animate')], + plugins: [animate], }; diff --git a/website/vite.config.ts b/website/vite.config.ts index e2ea07f00..692a8fd20 100644 --- a/website/vite.config.ts +++ b/website/vite.config.ts @@ -1,4 +1,4 @@ -import path from 'path'; +import path from 'node:path'; import { defineConfig } from 'vite'; import { nodePolyfills } from 'vite-plugin-node-polyfills'; import { TanStackRouterVite } from '@tanstack/router-vite-plugin';