Skip to content

Commit

Permalink
Merge pull request #10 from zetkin/231124-use=single-quote
Browse files Browse the repository at this point in the history
Use Eslint form app.zetkin
  • Loading branch information
richardolsson authored Nov 30, 2023
2 parents 96ce5fa + 609ffe4 commit cc8c0cd
Show file tree
Hide file tree
Showing 19 changed files with 988 additions and 410 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Lint

on:
push:
branches: [ "*" ]
pull_request:
branches: [ "main" ]

permissions:
contents: read

jobs:
lint:
name: Lint
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./webapp
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18.x
cache: 'yarn'
cache-dependency-path: ./webapp/yarn.lock
- run: yarn
- run: yarn lint
98 changes: 98 additions & 0 deletions webapp/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
module.exports = {
root: true,
env: {
node: true,
es6: true,
},
parserOptions: { ecmaVersion: 8 }, // to enable features such as async/await
// We don't want to lint generated files nor node_modules, but we want to lint .prettierrc.json (ignored by default by eslint)
ignorePatterns: ['node_modules/*', '.next/*', '.out/*', '!.prettierrc.json'],
extends: [
'eslint:recommended',
'next',
'prettier',
],
settings: { react: { version: 'detect' } },
overrides: [
// This configuration will apply only to TypeScript files
{
files: ['**/*.ts', '**/*.tsx', 'src/**/*.js'],
parser: '@typescript-eslint/parser',
env: {
browser: true,
node: true,
es6: true,
},
extends: [
'plugin:@typescript-eslint/recommended', // TypeScript rules
'plugin:react-hooks/recommended', // React hooks rules
'plugin:jsx-a11y/recommended', // Accessibility rules
],
plugins: ['no-switch-statements'],
rules: {
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-unused-vars': ['error'],
'@typescript-eslint/member-ordering': [
'error',
{
default: { memberTypes: 'never', order: 'alphabetically' },
interfaces: ['signature', 'method', 'constructor', 'field'],
},
],
curly: 'error',
'jsx-a11y/anchor-is-valid': 'off',
'no-console': 'error',
'no-switch-statements/no-switch': 'error',
'prefer-const': ['error', {}],
'react/jsx-handler-names': [
'error',
{
eventHandlerPrefix: 'on',
eventHandlerPropPrefix: 'on',
},
],
'react/jsx-no-target-blank': 'error',
'react/jsx-sort-props': [
'error',
{
ignoreCase: true,
reservedFirst: true,
},
],
'react/no-danger': 'error',
'react/no-deprecated': 'error',
'react/no-typos': 'error',
'react/no-unknown-property': 'error',
'react/no-unsafe': [
'error',
{
checkAliases: true,
},
],
'react/no-unused-prop-types': 'error',
'react/prefer-stateless-function': 'error',
'react/prop-types': 'off',
'react/react-in-jsx-scope': 'off',
'react-hooks/exhaustive-deps': 'off',
'react/self-closing-comp': [
'error',
{
component: true,
html: true,
},
],
'sort-imports': [
'error',
{
ignoreCase: true,
allowSeparatedGroups: true,
memberSyntaxSortOrder: ['none', 'all', 'single', 'multiple'],
},
],
'sort-keys': 'error',
'sort-vars': 'error',
},
},
],
};
3 changes: 0 additions & 3 deletions webapp/.eslintrc.json

This file was deleted.

19 changes: 19 additions & 0 deletions webapp/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# auto-generated localizations
src/locale/**/*.yml

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
.nyc_output

# next.js
/.next/
/out/

# production
/build
1 change: 0 additions & 1 deletion webapp/.prettierrc

This file was deleted.

3 changes: 3 additions & 0 deletions webapp/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"singleQuote": true
}
18 changes: 15 additions & 3 deletions webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint:eslint": "eslint .",
"lint:eslint-fix": "eslint . --fix",
"lint": "next lint"
},
"dependencies": {
Expand All @@ -23,9 +25,19 @@
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"eslint": "^8",
"eslint-config-next": "13.5.6",
"prettier": "^3.0.3",
"eslint": "^7.15.0",
"eslint-config-next": "^12.0.10",
"eslint-config-prettier": "^8.3.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-next": "^0.0.0",
"eslint-plugin-no-switch-statements": "^1.0.0",
"eslint-plugin-react": "^7.22.0",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-yml": "^0.13.0",
"@typescript-eslint/eslint-plugin": "^6",
"@typescript-eslint/parser": "^6",
"prettier": "^2.5.1",
"typescript": "^5"
}
}
31 changes: 15 additions & 16 deletions webapp/src/app/[lang]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
"use client";
'use client';

import MessageForm from "@/components/MessageForm";
import { MessageData } from "@/utils/readTypedMessages";
import { Box, Button, Link, Typography } from "@mui/joy";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import { MessageData } from '@/utils/readTypedMessages';
import MessageForm from '@/components/MessageForm';
import { Box, Button, Link, Typography } from '@mui/joy';
import { useEffect, useState } from 'react';

export default function Home({ params }: { params: { lang: string } }) {
const [messages, setMessages] = useState<MessageData[]>([]);
const [translations, setTranslations] = useState<Record<string, string>>({});
const [pullRequestUrl, setPullRequestUrl] = useState<string>("");
const [pullRequestUrl, setPullRequestUrl] = useState<string>('');

useEffect(() => {
async function loadMessages() {
const res = await fetch("/api/messages");
const res = await fetch('/api/messages');
const payload = await res.json();
setMessages(payload.data);
}
Expand All @@ -36,8 +35,8 @@ export default function Home({ params }: { params: { lang: string } }) {
<Typography level="h1">Messages</Typography>
<Button
onClick={async () => {
const res = await fetch(`/api/pull-request/`, {
method: "POST",
const res = await fetch('/api/pull-request/', {
method: 'POST',
});
const payload = await res.json();
const url = payload.pullRequestUrl;
Expand All @@ -57,23 +56,23 @@ export default function Home({ params }: { params: { lang: string } }) {
const res = await fetch(
`/api/translations/${params.lang}/${msg.id}`,
{
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
text,
}),
headers: {
'Content-Type': 'application/json',
},
method: 'PUT',
},
);

const payload = await res.json();
await res.json();
setTranslations((cur) => ({
...cur,
[msg.id]: text,
}));
}}
translation={translations[msg.id] || ""}
translation={translations[msg.id] || ''}
/>
);
})}
Expand Down
29 changes: 15 additions & 14 deletions webapp/src/app/api/languages.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,45 @@
import { envVarNotFound } from "@/utils/util";
import fs from "fs/promises";
import { parse } from "yaml";
import { simpleGit, SimpleGit, SimpleGitOptions } from "simple-git";
/* global globalThis */
import fs from 'fs/promises';
import { parse } from 'yaml';
import { envVarNotFound, logDebug } from '@/utils/util';
import { simpleGit, SimpleGit, SimpleGitOptions } from 'simple-git';

const REPO_PATH = process.env.REPO_PATH ?? envVarNotFound("REPO_PATH");
const MAIN_BRANCH = "main";
const REPO_PATH = process.env.REPO_PATH ?? envVarNotFound('REPO_PATH');
const MAIN_BRANCH = 'main';

export async function getLanguage(lang: string) {
let languages: Map<string, Record<string, unknown>>;
if (!globalThis.languages) {
console.debug("Initializing languages");
logDebug('Initializing languages');
const options: Partial<SimpleGitOptions> = {
baseDir: REPO_PATH,
binary: "git",
binary: 'git',
maxConcurrentProcesses: 1,
trimmed: false,
};
const git: SimpleGit = simpleGit(options);
console.debug("git checkout main pull...");
logDebug('git checkout main pull...');
await git.checkout(MAIN_BRANCH);
console.debug("git pull...");
logDebug('git pull...');
await git.pull();
console.debug("git done checkout main branch and pull");
logDebug('git done checkout main branch and pull');
languages = new Map<string, Record<string, unknown>>();
globalThis.languages = languages;
} else {
console.debug("read languages from globalThis");
logDebug('read languages from globalThis');
languages = globalThis.languages;
}

let translations: Record<string, unknown>;
if (!languages.has(lang)) {
console.debug("read languages from file");
logDebug('read languages from file');
const yamlPath = REPO_PATH + `/src/locale/${lang}.yml`;

const yamlBuf = await fs.readFile(yamlPath);
translations = parse(yamlBuf.toString()) as Record<string, unknown>;
languages.set(lang, translations);
} else {
console.debug("read languages from Memory");
logDebug('read languages from Memory');
translations = languages.get(lang) ?? throwLangNotFound(lang);
}

Expand Down
16 changes: 8 additions & 8 deletions webapp/src/app/api/messages/route.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { envVarNotFound } from "@/utils/util";
import fs from "fs/promises";
import path from "path";
import { NextResponse } from "next/server";
import { envVarNotFound } from '@/utils/util';
import fs from 'fs/promises';
import { NextResponse } from 'next/server';
import path from 'path';
import readTypedMessages, {
MessageData,
} from "@/utils/readTypedMessages";
} from '@/utils/readTypedMessages';

const REPO_PATH = process.env.REPO_PATH ?? envVarNotFound("REPO_PATH");
const REPO_PATH = process.env.REPO_PATH ?? envVarNotFound('REPO_PATH');

export async function GET() {
const messages: MessageData[] = [];
for await (const item of getMessageFiles(REPO_PATH + "/src")) {
for await (const item of getMessageFiles(REPO_PATH + '/src')) {
messages.push(...readTypedMessages(item));
}

Expand All @@ -26,7 +26,7 @@ async function* getMessageFiles(dirPath: string): AsyncGenerator<string> {
const stats = await fs.stat(itemPath);
if (stats.isDirectory()) {
yield* getMessageFiles(itemPath);
} else if (itemPath.endsWith("messageIds.ts")) {
} else if (itemPath.endsWith('messageIds.ts')) {
yield itemPath;
}
}
Expand Down
Loading

0 comments on commit cc8c0cd

Please sign in to comment.