From 97100af6d014960812c3d8a066ddcdab0fe908a7 Mon Sep 17 00:00:00 2001 From: MrOrz Date: Mon, 12 Feb 2024 23:15:43 +0700 Subject: [PATCH 1/8] chore: add prettier --- .eslintrc.json | 2 +- README.md | 4 ++ package-lock.json | 106 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 ++ 4 files changed, 114 insertions(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index bffb357..d9f228c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,3 +1,3 @@ { - "extends": "next/core-web-vitals" + "extends": ["next/core-web-vitals", "prettier", "plugin:prettier/recommended"] } diff --git a/README.md b/README.md index e46bf47..00ab364 100644 --- a/README.md +++ b/README.md @@ -23,3 +23,7 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the The main branch of this repository is automatically deployed to `https://dash.cofacts.tw`. +## Other scripts +- `npm run lint`: Run eslint (includes prettier). +- `npm run codegen`: Generates types for graphql queries. Useful when Typescript complains about.`TypedDocumentNode` for new or updated GraphQL queries. +- `npm run build` and `npm start`: Generate production build and start, respectively. diff --git a/package-lock.json b/package-lock.json index 59647a9..148b0f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,10 @@ "autoprefixer": "^10.0.1", "eslint": "^8", "eslint-config-next": "14.1.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.1.3", "postcss": "^8", + "prettier": "3.2.5", "tailwindcss": "^3.3.0", "typescript": "^5.3.3" }, @@ -2653,6 +2656,18 @@ "node": ">=14" } }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/@repeaterjs/repeater": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@repeaterjs/repeater/-/repeater-3.0.5.tgz", @@ -4449,6 +4464,18 @@ } } }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", @@ -4611,6 +4638,36 @@ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" } }, + "node_modules/eslint-plugin-prettier": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", + "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.6" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, "node_modules/eslint-plugin-react": { "version": "7.33.2", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", @@ -4816,6 +4873,12 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -7457,6 +7520,33 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", @@ -8373,6 +8463,22 @@ "tslib": "^2.0.3" } }, + "node_modules/synckit": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", + "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/tailwindcss": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz", diff --git a/package.json b/package.json index 51dca0a..e7c717f 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,10 @@ "autoprefixer": "^10.0.1", "eslint": "^8", "eslint-config-next": "14.1.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.1.3", "postcss": "^8", + "prettier": "3.2.5", "tailwindcss": "^3.3.0", "typescript": "^5.3.3" }, From 5ff8ac0d61b96e91c22c028075c409024f5965af Mon Sep 17 00:00:00 2001 From: MrOrz Date: Mon, 12 Feb 2024 23:15:55 +0700 Subject: [PATCH 2/8] fix: prettier --- app/page.tsx | 32 +++++++++++++++++--------------- typegen/gql.ts | 4 ++-- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index c84b8ad..54a76da 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,24 +1,26 @@ -import { request } from 'graphql-request'; -import { graphql } from '@/typegen/gql'; +import { request } from "graphql-request"; +import { graphql } from "@/typegen/gql"; async function getData() { - return request(process.env.COFACTS_API_URL ?? '', graphql(/* GraphQL */ ` - query LoadAPIStats { - allArticles: ListArticles { - totalCount + return request( + process.env.COFACTS_API_URL ?? "", + graphql(/* GraphQL */ ` + query LoadAPIStats { + allArticles: ListArticles { + totalCount + } + allRepliedArticles: ListArticles { + totalCount + } + articlesHasUsefulReplies: ListArticles { + totalCount + } } - allRepliedArticles: ListArticles { - totalCount - } - articlesHasUsefulReplies: ListArticles { - totalCount - } - } - `)); + `), + ); } export default async function Home() { - const resp = await getData(); return ( diff --git a/typegen/gql.ts b/typegen/gql.ts index 81c0747..28f4491 100644 --- a/typegen/gql.ts +++ b/typegen/gql.ts @@ -13,7 +13,7 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/ * Therefore it is highly recommended to use the babel or swc plugin for production. */ const documents = { - "\n query LoadAPIStats {\n allArticles: ListArticles {\n totalCount\n }\n allRepliedArticles: ListArticles {\n totalCount\n }\n articlesHasUsefulReplies: ListArticles {\n totalCount\n }\n }\n ": types.LoadApiStatsDocument, + "\n query LoadAPIStats {\n allArticles: ListArticles {\n totalCount\n }\n allRepliedArticles: ListArticles {\n totalCount\n }\n articlesHasUsefulReplies: ListArticles {\n totalCount\n }\n }\n ": types.LoadApiStatsDocument, }; /** @@ -33,7 +33,7 @@ export function graphql(source: string): unknown; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query LoadAPIStats {\n allArticles: ListArticles {\n totalCount\n }\n allRepliedArticles: ListArticles {\n totalCount\n }\n articlesHasUsefulReplies: ListArticles {\n totalCount\n }\n }\n "): (typeof documents)["\n query LoadAPIStats {\n allArticles: ListArticles {\n totalCount\n }\n allRepliedArticles: ListArticles {\n totalCount\n }\n articlesHasUsefulReplies: ListArticles {\n totalCount\n }\n }\n "]; +export function graphql(source: "\n query LoadAPIStats {\n allArticles: ListArticles {\n totalCount\n }\n allRepliedArticles: ListArticles {\n totalCount\n }\n articlesHasUsefulReplies: ListArticles {\n totalCount\n }\n }\n "): (typeof documents)["\n query LoadAPIStats {\n allArticles: ListArticles {\n totalCount\n }\n allRepliedArticles: ListArticles {\n totalCount\n }\n articlesHasUsefulReplies: ListArticles {\n totalCount\n }\n }\n "]; export function graphql(source: string) { return (documents as any)[source] ?? {}; From 9c88e7ecc5c4d76b232dd8b52c65411c289f2a1c Mon Sep 17 00:00:00 2001 From: MrOrz Date: Mon, 12 Feb 2024 23:24:08 +0700 Subject: [PATCH 3/8] chore: setup CI --- .github/workflows/ci.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b094a0c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,20 @@ +name: CI test + +on: + # Triggers the workflow on push or pull request events but only for the dev branch + - pull_request + - push + # Allows you to run this workflow manually from the Actions tab + - workflow_dispatch + +jobs: + install-and-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '20.x' + cache: 'npm' + - run: npm ci + - run: npm run lint From a1df7761f6e69437e24ec0c0d640097906e90feb Mon Sep 17 00:00:00 2001 From: MrOrz Date: Mon, 12 Feb 2024 23:33:53 +0700 Subject: [PATCH 4/8] refactor(.github): run build instead of just lint in CI --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b094a0c..d618c1f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,4 +17,5 @@ jobs: node-version: '20.x' cache: 'npm' - run: npm ci - - run: npm run lint + # Running build would lint and check type + - run: npm run build From b97aa5f6c3979643fcf2e0f938775981fc061742 Mon Sep 17 00:00:00 2001 From: MrOrz Date: Mon, 12 Feb 2024 23:55:09 +0700 Subject: [PATCH 5/8] refactor: setup prettier style config --- .eslintrc.json | 11 ++++++++++- app/layout.tsx | 12 ++++++------ app/page.tsx | 8 ++++---- codegen.ts | 8 ++++---- tailwind.config.ts | 14 +++++++------- 5 files changed, 31 insertions(+), 22 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index d9f228c..e4d7c83 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,3 +1,12 @@ { - "extends": ["next/core-web-vitals", "prettier", "plugin:prettier/recommended"] + "extends": ["next/core-web-vitals", "prettier", "plugin:prettier/recommended"], + "rules": { + "prettier/prettier": [ + "error", + { + "trailingComma": "es5", + "singleQuote": true + } + ] + } } diff --git a/app/layout.tsx b/app/layout.tsx index 3314e47..28da9d3 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,12 +1,12 @@ -import type { Metadata } from "next"; -import { Inter } from "next/font/google"; -import "./globals.css"; +import type { Metadata } from 'next'; +import { Inter } from 'next/font/google'; +import './globals.css'; -const inter = Inter({ subsets: ["latin"] }); +const inter = Inter({ subsets: ['latin'] }); export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: 'Create Next App', + description: 'Generated by create next app', }; export default function RootLayout({ diff --git a/app/page.tsx b/app/page.tsx index 54a76da..d2b6afd 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,9 +1,9 @@ -import { request } from "graphql-request"; -import { graphql } from "@/typegen/gql"; +import { request } from 'graphql-request'; +import { graphql } from '@/typegen/gql'; async function getData() { return request( - process.env.COFACTS_API_URL ?? "", + process.env.COFACTS_API_URL ?? '', graphql(/* GraphQL */ ` query LoadAPIStats { allArticles: ListArticles { @@ -16,7 +16,7 @@ async function getData() { totalCount } } - `), + `) ); } diff --git a/codegen.ts b/codegen.ts index 40ad82b..88ae5af 100644 --- a/codegen.ts +++ b/codegen.ts @@ -5,10 +5,10 @@ import type { CodegenConfig } from '@graphql-codegen/cli'; const config: CodegenConfig = { overwrite: true, schema: process.env.COFACTS_API_URL, - documents: ["app/**/*.tsx"], + documents: ['app/**/*.tsx'], generates: { 'typegen/': { - preset: "client", + preset: 'client', plugins: [], presetConfig: { fragmentMasking: false, @@ -19,8 +19,8 @@ const config: CodegenConfig = { skipTypename: true, avoidOptionals: true, }, - } - } + }, + }, }; export default config; diff --git a/tailwind.config.ts b/tailwind.config.ts index 7e4bd91..2686392 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,17 +1,17 @@ -import type { Config } from "tailwindcss"; +import type { Config } from 'tailwindcss'; const config: Config = { content: [ - "./pages/**/*.{js,ts,jsx,tsx,mdx}", - "./components/**/*.{js,ts,jsx,tsx,mdx}", - "./app/**/*.{js,ts,jsx,tsx,mdx}", + './pages/**/*.{js,ts,jsx,tsx,mdx}', + './components/**/*.{js,ts,jsx,tsx,mdx}', + './app/**/*.{js,ts,jsx,tsx,mdx}', ], theme: { extend: { backgroundImage: { - "gradient-radial": "radial-gradient(var(--tw-gradient-stops))", - "gradient-conic": - "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))", + 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', + 'gradient-conic': + 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', }, }, }, From 7ade9156d78ccf2069c98445ea5b268af3da3a73 Mon Sep 17 00:00:00 2001 From: MrOrz Date: Tue, 13 Feb 2024 00:00:01 +0700 Subject: [PATCH 6/8] fix(.github): include env in action --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d618c1f..7370fa0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,3 +19,5 @@ jobs: - run: npm ci # Running build would lint and check type - run: npm run build + env: + COFACTS_API_URL: ${{ env.COFACTS_API_URL }} From 42434b596145c9e0e3cf5bf01a79c3e13b16e8e6 Mon Sep 17 00:00:00 2001 From: MrOrz Date: Tue, 13 Feb 2024 00:04:12 +0700 Subject: [PATCH 7/8] fix(.github): hard code COFACTS_API_URL no point to read from repo --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7370fa0..68b2eb0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,4 +20,4 @@ jobs: # Running build would lint and check type - run: npm run build env: - COFACTS_API_URL: ${{ env.COFACTS_API_URL }} + COFACTS_API_URL: 'https://dev-api.cofacts.tw/graphql' From 4c36f4ab383351c1a5ec414cfe0ad36a174abdfb Mon Sep 17 00:00:00 2001 From: MrOrz Date: Tue, 13 Feb 2024 00:06:08 +0700 Subject: [PATCH 8/8] docs(README): add CI badge on README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 00ab364..2dc6355 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Cofacts Dashboard +[![CI test](https://github.com/cofacts/dashboard/actions/workflows/ci.yml/badge.svg)](https://github.com/cofacts/dashboard/actions/workflows/ci.yml) + Visualize the data of Cofacts fact-checking platform. ## Getting Started