Skip to content

Commit

Permalink
feat: add husky precommit and configure linter (#45)
Browse files Browse the repository at this point in the history
* add husky precommit and configure linter

* fix: all errors in the project (#46)

* fix all errors

* fix: fix all eslint warnings

Co-authored-by: Arnau Espin <[email protected]>
  • Loading branch information
evavirseda and aspnxdd authored Jan 17, 2023
1 parent 0f4365d commit b588e59
Show file tree
Hide file tree
Showing 23 changed files with 1,185 additions and 390 deletions.
122 changes: 122 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
const parserOptions = {
ecmaVersion: 6,
sourceType: 'module',
}

const eslintRules = {
'arrow-body-style': 'warn', // WARN b/c blocks style allows for readability and ensure scope
'arrow-spacing': 'error',
'eol-last': 'error',
'func-call-spacing': 'error',
'indent': 'off', // OFF b/c causes problems between Prettier and ESLint
'linebreak-style': 'off', // OFF b/c Windows (Git) puts CRLF line endings
'missing-declaration': 'off', // OFF b/c throws errors on imports / require statements
'multiline-ternary': 'off', // OFF b/c causes problems between Prettier and ESLint
'no-alert': 'error',
'no-async-promise-executor': 'error',
'no-case-declarations': 'error',
'no-console': ['error', { allow: ['error', 'warn'] }],
'no-control-regex': 'error',
'no-dupe-keys': 'error',
'no-empty': 'error',
'no-extra-boolean-cast': 'error',
'no-extra-parens': 'off',
'no-extra-semi': 'error',
'no-fallthrough': 'error',
'no-import-assign': 'error',
'no-irregular-whitespace': 'error',
'no-prototype-builtins': 'error',
'no-return-await': 'error',
'no-trailing-spaces': 'error',
'no-useless-escape': 'error',
'no-undef': 'error',
'no-underscore-dangle': 'off', // OFF b/c this syntax is used for defining local callback methods
'no-unreachable': 'error',
'no-unused-export-let': 'off', // OFF b/c troublesome with some .js files in packages/shared
'no-unused-vars': 'off', // OFF b/c there are simply too many and they're harmless
'no-var': 'error',
'prefer-arrow-callback': 'warn',
'prefer-const': 'warn',
'prefer-destructuring': 'off', // OFF b/c it's not really correct
'quotes': ['error', 'single'],
'semi': 'off', // OFF b/c we aren't using semicolons
'space-before-function-paren': 'off', // OFF b/c we aren't using spaces before function parameters / signatures
'spaced-comment': 'error',
}

const eslintRulesOnlyTypescript = {
'no-undef': 'off' // Typescript handles undefined variables better than eslint
}

const typescriptEslintRules = {
'@typescript-eslint/array-type': 'error',
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/ban-types': 'error',
'@typescript-eslint/ban-ts-comment': 'warn',
'@typescript-eslint/explicit-module-boundary-types': 'error',
'@typescript-eslint/no-array-constructor': 'error',
'@typescript-eslint/no-empty-function': 'off', // OFF b/c we use empty functions a lot (esp. for initialization)
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-extra-non-null-assertion': 'error',
'@typescript-eslint/no-extra-semi': 'error',
'@typescript-eslint/no-floating-promises': 'warn', // Warn b/c we have existing code in migration that I don't want to touch to pass new linting rules
'@typescript-eslint/no-implied-eval': 'error',
'@typescript-eslint/no-inferrable-types': 'off', // OFF b/c this errors on some useful code annotations for function signatures
'@typescript-eslint/no-misused-new': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/no-non-null-asserted-optional-chain': 'error',
'@typescript-eslint/no-non-null-assertion': 'error',
'@typescript-eslint/no-this-alias': 'error',
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off', // OFF b/c there are simply too many linting errors
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unused-vars': 'off', // OFF b/c there are simply too many and they're harmless
'@typescript-eslint/no-var-requires': 'error',
'@typescript-eslint/prefer-regexp-exec': 'error',
'@typescript-eslint/restrict-plus-operands': 'off', // OFF b/c not entirely accurate despite proper typings
'@typescript-eslint/restrict-template-expressions': 'off', // OFF b/c using any is useful in template expressions
'@typescript-eslint/require-await': 'error',
'@typescript-eslint/unbound-method': 'error',
}


module.exports = {
env: {
browser: true,
es6: true,
node: true,
},
extends: ['eslint:recommended', 'plugin:@next/next/recommended'],
overrides: [
{
files: ['**/*.ts', '**/*.tsx'],
extends: [
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
],
parser: '@typescript-eslint/parser',
parserOptions: {
...parserOptions,
project: './tsconfig.json',
tsconfigRootDir: './',
},
plugins: ['@typescript-eslint'],
rules: {
...eslintRules,
...eslintRulesOnlyTypescript,
...typescriptEslintRules,
},
},
],
parser: '@babel/eslint-parser',
parserOptions: {
...parserOptions,
requireConfigFile: false,
},
rules: {
...eslintRules,
},
}
3 changes: 0 additions & 3 deletions .eslintrc.json

This file was deleted.

4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged --allow-empty
19 changes: 9 additions & 10 deletions components/Layout/Flash.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { StyledOcticon, Flash } from "@primer/react";
import { CheckIcon } from "@primer/octicons-react";
import { useHandleDestroyAnimated } from "hooks";
import { useEffect, useRef } from "react";
import { useSuccess, useConnection } from "contexts";
import { StyledOcticon, Flash } from '@primer/react';
import { CheckIcon } from '@primer/octicons-react';
import { useHandleDestroyAnimated } from 'hooks';
import { useEffect, useRef } from 'react';
import { useSuccess, useConnection } from 'contexts';

const Toast: React.FC = () => {
const flashRef = useRef<null | HTMLDivElement>(null);
Expand All @@ -14,27 +14,26 @@ const Toast: React.FC = () => {
);

useEffect(() => {
if (message === "") return;
if (message === '') return;
setSendSuccess(true);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [message]);

const queryParam = url?.includes("devnet") ? "?cluster=devnet-solana" : "";
const queryParam = url?.includes('devnet') ? '?cluster=devnet-solana' : '';

if (sendSuccess)
return (
<div ref={flashRef} id="send-success">
<Flash
variant="success"
sx={{ display: "flex", flexDirection: "column" }}
sx={{ display: 'flex', flexDirection: 'column' }}
>
<span>
<StyledOcticon icon={CheckIcon} />
<strong>{message}</strong>
</span>
{mint && (
<a
style={{ textDecoration: "underline", color: "#423939" }}
style={{ textDecoration: 'underline', color: '#423939' }}
href={`https://solana.fm/address/${mint}${queryParam}`}
>
<i>View token</i>
Expand Down
28 changes: 13 additions & 15 deletions components/Layout/FontanaSVG.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
const FontanaSVG: React.FC<{ width: number }> = ({ width }) => {
return (
<svg
width={width}
viewBox="0 0 243 356"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M235.713 111.422C226.622 101.841 211.31 100.41 202.991 100.41C199.881 100.41 196.793 100.601 193.815 100.977C167.84 104.261 148.09 105.899 129.608 106.259C128.459 102.261 126.249 98.299 122.022 98.1C122.315 91.387 122.937 84.675 123.936 78.034C125.211 69.541 126.897 60.552 130.788 52.814C132.544 49.319 135.03 46.005 138.481 44.039C142.094 41.979 146.345 41.736 150.338 42.671C153.744 43.469 157.038 45.033 159.815 47.166C162.09 48.914 163.751 52.002 167.12 50.954C170.593 49.874 171.165 45.587 168.71 43.219C168.741 43.249 168.788 43.295 168.707 43.216C168.682 43.192 168.689 43.199 168.702 43.212C160.668 35.582 146.553 32.284 136.698 38.134C125.374 44.854 123.55 60.073 122.22 71.92C121.949 63.604 122.631 55.159 123.135 46.858C123.674 37.963 124.233 28.969 125.841 20.192C126.571 16.207 127.633 12.409 130.239 9.206C132.688 6.191 136.266 4.571 140.155 4.908C143.772 5.221 147.544 6.905 150.176 9.417C151.042 10.244 151.627 11.186 152.91 11.417C154.519 11.707 156.142 10.716 156.609 9.146C157.464 6.272 154.074 4.279 152.001 3.103C149.053 1.43 145.719 0.348996 142.336 0.0639957C134.795 -0.571004 128.609 3.62 125.693 10.476C122.664 17.594 122.486 25.921 122.058 33.536C121.587 41.925 121.443 50.335 121.407 58.736C120.205 46.719 118.014 31.458 105.96 25.358C98.766 21.717 90.063 22.719 82.92 25.97C79.955 27.32 77.221 29.062 74.852 31.304C72.508 33.522 73.129 37.539 76.168 38.795C79.707 40.257 81.536 36.883 83.97 35.115C87.164 32.745 90.998 31.075 94.94 30.502C99.536 29.833 104.036 30.973 107.542 34.065C110.151 36.366 112.068 39.552 113.388 42.745C116.566 50.433 118.115 59.754 119.232 68.268C119.998 74.133 120.562 80.02 120.984 85.919C121.173 88.568 121.336 91.218 121.466 93.87C121.534 95.255 121.487 96.687 121.61 98.085C117.224 98.139 114.957 102.187 113.785 106.261C95.303 105.901 75.553 104.263 49.578 100.979C46.599 100.603 43.512 100.412 40.402 100.412C32.082 100.412 16.77 101.842 7.679 111.423C2.9 116.461 0.582994 123.119 0.979994 130.677C1.08399 132.609 2.111 134.374 3.741 135.417C5.372 136.459 7.405 136.651 9.202 135.933C15.723 133.325 21.582 132.057 27.119 132.057C36.924 132.057 46.012 136.008 57.497 142.381C70.994 149.872 85.371 154.147 102.715 155.713C99.787 171.144 94.887 190.399 86.19 213.67C68.633 260.645 76.651 294.978 89.667 313.103C81.616 327.28 71.397 353.931 107.271 355.395H119.776H123.622H136.127C172 353.931 161.781 327.281 153.731 313.103C166.747 294.978 174.763 260.645 157.208 213.67C148.511 190.399 143.61 171.144 140.683 155.713C158.027 154.147 172.404 149.872 185.9 142.381C197.386 136.007 206.474 132.057 216.279 132.057C221.814 132.057 227.675 133.325 234.196 135.933C235.994 136.653 238.026 136.46 239.657 135.417C241.287 134.375 242.314 132.609 242.417 130.677C242.81 123.118 240.493 116.461 235.713 111.422Z"
fill="white"
/>
</svg>
);
};
const FontanaSVG: React.FC<{ width: number }> = ({ width }) => (
<svg
width={width}
viewBox="0 0 243 356"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M235.713 111.422C226.622 101.841 211.31 100.41 202.991 100.41C199.881 100.41 196.793 100.601 193.815 100.977C167.84 104.261 148.09 105.899 129.608 106.259C128.459 102.261 126.249 98.299 122.022 98.1C122.315 91.387 122.937 84.675 123.936 78.034C125.211 69.541 126.897 60.552 130.788 52.814C132.544 49.319 135.03 46.005 138.481 44.039C142.094 41.979 146.345 41.736 150.338 42.671C153.744 43.469 157.038 45.033 159.815 47.166C162.09 48.914 163.751 52.002 167.12 50.954C170.593 49.874 171.165 45.587 168.71 43.219C168.741 43.249 168.788 43.295 168.707 43.216C168.682 43.192 168.689 43.199 168.702 43.212C160.668 35.582 146.553 32.284 136.698 38.134C125.374 44.854 123.55 60.073 122.22 71.92C121.949 63.604 122.631 55.159 123.135 46.858C123.674 37.963 124.233 28.969 125.841 20.192C126.571 16.207 127.633 12.409 130.239 9.206C132.688 6.191 136.266 4.571 140.155 4.908C143.772 5.221 147.544 6.905 150.176 9.417C151.042 10.244 151.627 11.186 152.91 11.417C154.519 11.707 156.142 10.716 156.609 9.146C157.464 6.272 154.074 4.279 152.001 3.103C149.053 1.43 145.719 0.348996 142.336 0.0639957C134.795 -0.571004 128.609 3.62 125.693 10.476C122.664 17.594 122.486 25.921 122.058 33.536C121.587 41.925 121.443 50.335 121.407 58.736C120.205 46.719 118.014 31.458 105.96 25.358C98.766 21.717 90.063 22.719 82.92 25.97C79.955 27.32 77.221 29.062 74.852 31.304C72.508 33.522 73.129 37.539 76.168 38.795C79.707 40.257 81.536 36.883 83.97 35.115C87.164 32.745 90.998 31.075 94.94 30.502C99.536 29.833 104.036 30.973 107.542 34.065C110.151 36.366 112.068 39.552 113.388 42.745C116.566 50.433 118.115 59.754 119.232 68.268C119.998 74.133 120.562 80.02 120.984 85.919C121.173 88.568 121.336 91.218 121.466 93.87C121.534 95.255 121.487 96.687 121.61 98.085C117.224 98.139 114.957 102.187 113.785 106.261C95.303 105.901 75.553 104.263 49.578 100.979C46.599 100.603 43.512 100.412 40.402 100.412C32.082 100.412 16.77 101.842 7.679 111.423C2.9 116.461 0.582994 123.119 0.979994 130.677C1.08399 132.609 2.111 134.374 3.741 135.417C5.372 136.459 7.405 136.651 9.202 135.933C15.723 133.325 21.582 132.057 27.119 132.057C36.924 132.057 46.012 136.008 57.497 142.381C70.994 149.872 85.371 154.147 102.715 155.713C99.787 171.144 94.887 190.399 86.19 213.67C68.633 260.645 76.651 294.978 89.667 313.103C81.616 327.28 71.397 353.931 107.271 355.395H119.776H123.622H136.127C172 353.931 161.781 327.281 153.731 313.103C166.747 294.978 174.763 260.645 157.208 213.67C148.511 190.399 143.61 171.144 140.683 155.713C158.027 154.147 172.404 149.872 185.9 142.381C197.386 136.007 206.474 132.057 216.279 132.057C221.814 132.057 227.675 133.325 234.196 135.933C235.994 136.653 238.026 136.46 239.657 135.417C241.287 134.375 242.314 132.609 242.417 130.677C242.81 123.118 240.493 116.461 235.713 111.422Z"
fill="white"
/>
</svg>
);

export default FontanaSVG;
34 changes: 16 additions & 18 deletions components/Layout/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import { FontanaSVG } from "components/Layout";
import { NetworkSelector, Wallet } from "components/Layout";
import { FontanaSVG } from 'components/Layout';
import { NetworkSelector, Wallet } from 'components/Layout';

const Header: React.FC = () => {
return (
<nav>
<div className="d-flex flex-justify-center flex-items-center">
<FontanaSVG width={27} />
<h4 className="ml-3 text-bold color-white" style={{ color: "white" }}>
Fontana - A simple dashboard to manage Solana SPL tokens
</h4>
</div>
<div className="d-flex flex-justify-center flex-items-center">
<NetworkSelector />
<Wallet />
</div>
</nav>
);
};
const Header: React.FC = () => (
<nav>
<div className="d-flex flex-justify-center flex-items-center">
<FontanaSVG width={27} />
<h4 className="ml-3 text-bold color-white" style={{ color: 'white' }}>
Fontana - A simple dashboard to manage Solana SPL tokens
</h4>
</div>
<div className="d-flex flex-justify-center flex-items-center">
<NetworkSelector />
<Wallet />
</div>
</nav>
);

export default Header;
34 changes: 19 additions & 15 deletions components/Layout/NetworkSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { FC, useEffect, useRef } from "react";
import { WalletAdapterNetwork } from "@solana/wallet-adapter-base";
import { clusterApiUrl, Connection } from "@solana/web3.js";
import { Network, useConnection } from "contexts";
import { FC, useEffect, useRef } from 'react';
import { WalletAdapterNetwork } from '@solana/wallet-adapter-base';
import { clusterApiUrl, Connection } from '@solana/web3.js';
import { Network, useConnection } from 'contexts';

const RPC_API_DEVNET =
process.env.NEXT_PUBLIC_RPC_API_DEVNET || clusterApiUrl("devnet");
process.env.NEXT_PUBLIC_RPC_API_DEVNET || clusterApiUrl('devnet');
const RPC_API_MAINNET =
process.env.NEXT_PUBLIC_RPC_API_MAINNET || clusterApiUrl("mainnet-beta");
process.env.NEXT_PUBLIC_RPC_API_MAINNET || clusterApiUrl('mainnet-beta');

function getUrl(network: Network): string {
switch (network) {
case "Devnet":
case 'Devnet':
return RPC_API_DEVNET;
case "Mainnet":
case 'Mainnet':
return RPC_API_MAINNET;
default:
throw new Error(`Unknown network: ${network}`);
Expand All @@ -24,23 +24,27 @@ const NetworkSelector: FC = () => {
const detailsRef = useRef<HTMLDetailsElement>(null);

function hideUl() {
detailsRef.current!.removeAttribute("open");
detailsRef.current?.removeAttribute('open');
}

function changeNetwork(_network: Network) {
setNetwork(_network);
setConnection(new Connection(getUrl(_network)));
setUrl(getUrl(_network));
localStorage.setItem("network-fontana", _network);
localStorage.setItem('network-fontana', _network);
}

useEffect(() => {
const _network = localStorage.getItem("network-fontana") as Network | null;
if (_network === "Devnet" || _network === "Mainnet" || _network === "Testnet") {
const _network = localStorage.getItem('network-fontana') as Network | null;
if (
_network === 'Devnet' ||
_network === 'Mainnet' ||
_network === 'Testnet'
) {
changeNetwork(_network);
return;
}
changeNetwork("Devnet");
changeNetwork('Devnet');
}, []);

return (
Expand All @@ -51,13 +55,13 @@ const NetworkSelector: FC = () => {
ref={detailsRef}
>
<summary className="btn" aria-haspopup="true">
{network || "Select Network"}
{network || 'Select Network'}
<span className="dropdown-caret"></span>
</summary>
{
<ul id="ul" className="dropdown-menu dropdown-menu-se mt-2">
{Object.keys(WalletAdapterNetwork)
.filter((e) => e !== "Testnet")
.filter((e) => e !== 'Testnet')
.map((_network) => (
<li
className="dropdown-item"
Expand Down
26 changes: 12 additions & 14 deletions components/Layout/Wallet.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { WalletMultiButton } from "@solana/wallet-adapter-react-ui";
import { FC } from "react";
import { WalletMultiButton } from '@solana/wallet-adapter-react-ui';
import { FC } from 'react';

const Wallet: FC = () => {
return (
<div
className="d-flex "
style={{
transform: "scale(0.7)",
}}
>
<WalletMultiButton />
</div>
);
};
const Wallet: FC = () => (
<div
className="d-flex "
style={{
transform: 'scale(0.7)',
}}
>
<WalletMultiButton />
</div>
);

export default Wallet;
10 changes: 5 additions & 5 deletions components/Layout/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export { default as Wallet } from "./Wallet";
export { default as Header } from "./Header";
export { default as FontanaSVG } from "./FontanaSVG";
export { default as NetworkSelector } from "./NetworkSelector";
export { default as Toast } from "./Flash";
export { default as Wallet } from './Wallet';
export { default as Header } from './Header';
export { default as FontanaSVG } from './FontanaSVG';
export { default as NetworkSelector } from './NetworkSelector';
export { default as Toast } from './Flash';
Loading

0 comments on commit b588e59

Please sign in to comment.