feat: setup linters (#357)

Co-authored-by: Roland Bewick <roland.bewick@gmail.com>
This commit is contained in:
Pavan Joshi 2024-06-01 12:35:43 +05:30 committed by GitHub
parent 369a7304bf
commit 3e5925387a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 1092 additions and 162 deletions

2
frontend/.eslintignore Normal file
View file

@ -0,0 +1,2 @@
node_modules
dist

View file

@ -2,17 +2,28 @@ module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended",
"prettier",
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
ignorePatterns: ["dist", ".eslintrc.cjs"],
parser: "@typescript-eslint/parser",
plugins: ["react-refresh", "@typescript-eslint"],
rules: {
'react-refresh/only-export-components': [
'warn',
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
"@typescript-eslint/ban-ts-comment": [
"error",
{
"ts-ignore": "allow-with-description",
},
],
"@typescript-eslint/no-unused-vars": ["warn", { args: "none" }],
"no-console": ["error", { allow: ["info", "warn", "error"] }],
"no-constant-binary-expression": "error",
curly: "error",
},
}
};

View file

@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
cd frontend && yarn commitlint --edit

View file

@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
cd frontend && yarn lint-staged

3
frontend/.prettierignore Normal file
View file

@ -0,0 +1,3 @@
# Ignore artifacts:
dist
node_modules

3
frontend/.prettierrc Normal file
View file

@ -0,0 +1,3 @@
{
"trailingComma": "es5"
}

View file

@ -0,0 +1 @@
export default { extends: ['@commitlint/config-conventional'] };

View file

@ -0,0 +1,6 @@
export default {
"src/**/*.{ts,tsx,json}": ["eslint --fix --max-warnings 0","prettier --write"],
"platform_specific/**/*.ts": ["prettier --write"],
"package.json": ["prettier --write"],
"src/**/*.ts": () => "tsc --noEmit",
};

View file

@ -10,8 +10,14 @@
"build:wails": "yarn prepare:wails && tsc && vite build",
"prepare:wails": "shx cp ./platform_specific/wails/src/utils/*.ts src/utils/",
"prepare:http": "shx cp ./platform_specific/http/src/utils/*.ts src/utils/",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
"lint": "yarn lint:js && yarn tsc:compile && yarn format:fix --report-unused-disable-directives --max-warnings 0",
"lint:js": "eslint src --ext .js,.ts,.tsx --max-warnings 0",
"lint:js:fix": "eslint src --ext .js,.ts,.tsx --fix",
"tsc:compile": "tsc --noEmit",
"format": "prettier --check '**/*.(md|json)' 'src/**/*.(js|ts)' 'example/**/*.(js|jsx)'",
"format:fix": "prettier --loglevel silent --write '**/*.(md|json)' 'src/**/*.(js|ts)' 'example/**/*.(js|jsx)'",
"preview": "vite preview",
"prepare": "cd .. && husky frontend/.husky"
},
"dependencies": {
"@getalby/bitcoin-connect-react": "^3.4.1",
@ -51,6 +57,8 @@
"zustand": "^4.5.0"
},
"devDependencies": {
"@commitlint/cli": "^19.3.0",
"@commitlint/config-conventional": "^19.2.2",
"@tailwindcss/aspect-ratio": "^0.4.2",
"@tailwindcss/forms": "^0.5.7",
"@tailwindcss/typography": "^0.5.10",
@ -59,14 +67,18 @@
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@types/react-lottie": "^1.2.10",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"@typescript-eslint/eslint-plugin": "^7.11.0",
"@typescript-eslint/parser": "^7.11.0",
"@vitejs/plugin-react-swc": "^3.3.2",
"autoprefixer": "^10.4.16",
"eslint": "^8.45.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
"husky": "^9.0.11",
"lint-staged": "^15.2.5",
"postcss": "^8.4.32",
"prettier": "3.2.5",
"shx": "^0.3.4",
"tailwindcss": "^3.4.1",
"typescript": "^5.0.2",

View file

@ -1,6 +1,12 @@
import { CopyIcon } from "lucide-react";
import { useEffect, useState } from "react";
import { Link, Navigate, useLocation, useNavigate, useParams } from "react-router-dom";
import {
Link,
Navigate,
useLocation,
useNavigate,
useParams,
} from "react-router-dom";
import AppHeader from "src/components/AppHeader";
import ExternalLink from "src/components/ExternalLink";
import Loading from "src/components/Loading";
@ -8,7 +14,12 @@ import Loading from "src/components/Loading";
import QRCode from "src/components/QRCode";
import { suggestedApps } from "src/components/SuggestedAppData";
import { Button } from "src/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "src/components/ui/card";
import {
Card,
CardContent,
CardHeader,
CardTitle,
} from "src/components/ui/card";
import { useToast } from "src/components/ui/use-toast";
import { useApp } from "src/hooks/useApp";
import { copyToClipboard } from "src/lib/clipboard";
@ -21,21 +32,16 @@ export default function AppConnect() {
const params = useParams();
const [timeout, setTimeout] = useState(false);
const createAppResponse = state as CreateAppResponse;
const appstoreApp = suggestedApps.find(x => x.id == params.id);
const appstoreApp = suggestedApps.find((x) => x.id == params.id);
const { data: app } = useApp(createAppResponse.pairingPublicKey, true);
const pairingUri = createAppResponse.pairingUri;
if (!createAppResponse || !appstoreApp) {
return <Navigate to="/apps/new" />;
}
const copy = () => {
copyToClipboard(pairingUri);
toast({ title: "Copied to clipboard." });
};
useEffect(() => {
const timeoutId = window.setTimeout(() => {
setTimeout(true);
}, 10000);
@ -47,11 +53,15 @@ export default function AppConnect() {
if (app?.lastEventAt) {
toast({
title: "Connection established!",
description: "You can now use the app with your Alby Hub."
description: "You can now use the app with your Alby Hub.",
});
navigate("/apps");
}
}, [app?.lastEventAt])
}, [app?.lastEventAt, navigate, toast]);
if (!createAppResponse || !appstoreApp) {
return <Navigate to="/apps/new" />;
}
return (
<>
@ -63,15 +73,16 @@ export default function AppConnect() {
<div>
<p>
1. Open{" "}
<ExternalLink className="font-semibold underline" to={appstoreApp.to}>
<ExternalLink
className="font-semibold underline"
to={appstoreApp.to}
>
{appstoreApp.title}
</ExternalLink>
{" "}
and look for a way to attach a wallet (most apps provide this option in settings)
</p>
<p>
2. Scan or paste the connection secret
</ExternalLink>{" "}
and look for a way to attach a wallet (most apps provide this option
in settings)
</p>
<p>2. Scan or paste the connection secret</p>
</div>
<Card className="max-w-sm">
<CardHeader>
@ -82,19 +93,18 @@ export default function AppConnect() {
<Loading className="w-4 h-4" />
<p>Waiting for app to connect</p>
</div>
{timeout && <div className="text-sm flex flex-col gap-2 items-center text-center">
Connecting is taking longer than usual.
<Link to={`/apps/${app?.nostrPubkey}`}>
<Button variant="secondary">Continue anyway</Button>
</Link>
</div>}
<a
href={pairingUri}
target="_blank"
className="relative"
>
{timeout && (
<div className="text-sm flex flex-col gap-2 items-center text-center">
Connecting is taking longer than usual.
<Link to={`/apps/${app?.nostrPubkey}`}>
<Button variant="secondary">Continue anyway</Button>
</Link>
</div>
)}
<a href={pairingUri} target="_blank" className="relative">
<QRCode value={pairingUri} className="w-full" />
<img src={appstoreApp.logo}
<img
src={appstoreApp.logo}
className="absolute w-12 h-12 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-muted p-1 rounded-xl"
/>
</a>

View file

@ -6,25 +6,24 @@ import { Button } from "src/components/ui/button";
import { Separator } from "src/components/ui/separator";
import { toast } from "src/components/ui/use-toast";
import { useCSRF } from "src/hooks/useCSRF";
import { AppPermissions, CreateAppResponse, NIP_47_NOTIFICATIONS_PERMISSION, PermissionType, nip47MethodDescriptions } from "src/types";
import {
AppPermissions,
CreateAppResponse,
PermissionType,
nip47PermissionDescriptions,
} from "src/types";
import { handleRequestError } from "src/utils/handleRequestError";
import { request } from "src/utils/request";
import Permissions from "../../components/Permissions";
// TODO: merge with nip47MethodDescriptions
export const nip47PermissionDescriptions: Record<PermissionType, string> = {
...nip47MethodDescriptions,
[NIP_47_NOTIFICATIONS_PERMISSION]: "Receive wallet notifications",
};
export default function AppDetail() {
const params = useParams();
const navigate = useNavigate();
const { data: csrf } = useCSRF();
const app = suggestedApps.find(x => x.id == params.id);
const app = suggestedApps.find((x) => x.id == params.id);
const methods = Object.keys(nip47PermissionDescriptions)
const methods = Object.keys(nip47PermissionDescriptions);
const requestMethodsSet = new Set<PermissionType>(
methods as PermissionType[]
);
@ -69,8 +68,9 @@ export default function AppDetail() {
}
};
if (!app)
if (!app) {
return;
}
return (
<>
@ -78,9 +78,11 @@ export default function AppDetail() {
title={`Connect to ${app.title}`}
description="Configure wallet permissions for the app and follow instructions to finalise the connection"
/>
<form onSubmit={handleSubmit} acceptCharset="UTF-8"
className="flex flex-col items-start gap-5 max-w-lg">
<form
onSubmit={handleSubmit}
acceptCharset="UTF-8"
className="flex flex-col items-start gap-5 max-w-lg"
>
<div className="flex flex-row items-center gap-3">
<img src={app.logo} className="h-12 w-12" />
<h2 className="font-semibold text-lg">{app.title}</h2>
@ -98,10 +100,7 @@ export default function AppDetail() {
<Separator />
<Button type="submit">
Create Connection
</Button>
<Button type="submit">Create Connection</Button>
</form>
</>
);

File diff suppressed because it is too large Load diff

View file

@ -32,7 +32,6 @@ func (svc *Service) StartNostr(ctx context.Context, encryptionKey string) error
svc.wg.Add(1)
go func() {
//Start infinite loop which will be only broken by canceling ctx (SIGINT)
//TODO: we can start this loop for multiple relays
var relay *nostr.Relay
for i := 0; ; i++ {