From bc351361d1899d18fb5cafce4bf2a5258de876d1 Mon Sep 17 00:00:00 2001 From: Yam Borodetsky Date: Thu, 28 Sep 2023 00:49:10 +0300 Subject: [PATCH] feat: lint (#44) + add lint as pre-commit hook and on pr workflow + add convenience scripts + lint and format + document in CONTRIBUTING.md --- .github/workflows/{deploy.yml => docs.yml} | 0 .github/workflows/test.yml | 34 ++++++++ .husky/pre-commit | 4 + .vscode/settings.json | 4 +- CONTRIBUTING.md | 95 +++++++-------------- bun.lockb | Bin 65606 -> 86536 bytes db/config.ts | 24 +++--- db/migrations/meta/0000_snapshot.json | 2 +- db/migrations/meta/_journal.json | 2 +- db/migrations/migrate.ts | 10 ++- db/seed.ts | 24 +++--- docs/.vitepress/config.mts | 22 ++--- package.json | 16 +++- renovate.json | 11 +-- src/app.module.ts | 6 +- src/database.providers.ts | 6 +- src/main.ts | 8 +- src/users/users.module.ts | 8 +- src/users/users.plugin.ts | 10 +-- src/users/users.repository.ts | 4 +- src/users/users.schema.ts | 32 +++---- src/users/users.service.ts | 2 +- 22 files changed, 170 insertions(+), 154 deletions(-) rename .github/workflows/{deploy.yml => docs.yml} (100%) create mode 100644 .github/workflows/test.yml create mode 100755 .husky/pre-commit diff --git a/.github/workflows/deploy.yml b/.github/workflows/docs.yml similarity index 100% rename from .github/workflows/deploy.yml rename to .github/workflows/docs.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..66db2f9 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,34 @@ +name: Lint, format, and test + +on: + pull_request: + branches: [main] + +jobs: + lint: + name: Lint and format + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Bun + uses: oven-sh/setup-bun@v1 + + - name: Lint and format the code + run: bunx biome ci --linter-enabled=true --formatter-enabled=true . + + test: + name: Test + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Bun + uses: oven-sh/setup-bun@v1 + + - name: Test the code + run: bun test diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..1d67559 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +bun lint-staged diff --git a/.vscode/settings.json b/.vscode/settings.json index ff30c44..78664b2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,3 @@ { - "editor.tabSize": 2 -} \ No newline at end of file + "editor.tabSize": 2 +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fecf225..78f5441 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,24 +12,12 @@ Hey there! We're thrilled that you'd like to contribute to this project. Your he > [!NOTE] > **Windows users**: see [special note](#special-note-for-windows-users) below. -This project uses [Bun](https://bun.sh) as a runtime as well as a package manager. You'll need to install it and use as your package manager for this project. it We recommend using [antfu/ni](https://github.com/antfu/ni) to avoid worrying about package managers when switching projects. +This project uses [Bun](https://bun.sh) as a runtime as well as a package manager. It's a modern, fast, and lightweight alternative to [Node.js](https://nodejs.org/en/) and [npm](https://www.npmjs.com/). To install Bun, run the following command: -We will use `ni`'s commands in the following code snippets. If you are not using it, you can run `bun i` instead of `ni`, and `bun run` instead of `nr`. - -* **Install the latest version of [Bun](https://bun.sh)** ```sh curl -fsSL https://bun.sh/install | bash ``` -* **Install [@antfu/ni](https://github.com/antfu/ni)** - ```sh - bun i -g @antfu/ni - ``` - -* **Install dependencies** - ```sh - ni - ``` ### Special note for Windows users @@ -37,33 +25,27 @@ This guide assumes you are using a Unix-like environment, since [Bun is working ## 💡 Commands -### `nr dev` - -Start the development environment. - -If it's a Node.js package, it will start the build process in watch mode, or [stub the passive watcher when using `unbuild`](https://antfu.me/posts/publish-esm-and-cjs#stubbing). +### `bun dev` -If it's a frontend project, it usually starts the dev server. You can then develop and see the changes in real time. +Start the development environment in watch mode. -### `nr play` +### `bun build` -If it's a Node.js package, it starts a dev server for the playground. The code is usually under `playground/`. +Build the project for production. The result is under `dist/`. -### `nr build` +### `bun lint` -Build the project for production. The result is usually under `dist/`. +We use [Biome](https://biomejs.dev/) for **both linting and formatting**. It is an ultra-fast, Rust based linter and formatter. +It also lints JSON. -### `nr lint` - -We use [ESLint](https://eslint.org/) for **both linting and formatting**. It also lints for JSON, YAML and Markdown files if exists. - -You can run `nr lint --fix` to let ESLint formats and lints the code. - -Learn more about the [ESLint Setup](#eslint). +You can run `bun lint --apply` to apply any safe fixes automatically. [**We don't use Prettier**](#no-prettier). -### `nr test` +### `bun test` + +> [!NOTE] +> This is just a placeholder for now. We will add more details later once tests are formally added. Run the tests. We mostly using [Vitest](https://vitest.dev/) - a replacement of [Jest](https://jestjs.io/). @@ -75,13 +57,13 @@ Vitest runs in [watch mode by default](https://vitest.dev/guide/features.html#wa For some projects, we might have multiple types of tests set up. For example `nr test:unit` for unit tests, `nr test:e2e` for end-to-end tests. `nr test` commonly run them together, you can run them separately as needed. -### `nr docs` +### `bun docs` -If the project contains documentation, you can run `nr docs` to start the documentation dev server. Use `nr docs:build` to build the docs for production. +Start the documentation dev server. Use `bun docs:build` to build the docs for production. -### `nr` +### `bun run` -For more, you can run bare `nr`, which will prompt a list of all available scripts. +Print a full list of available scripts. ## 🙌 The Road to a Great Pull Request @@ -143,7 +125,7 @@ When ready to publish a new release, we run `nr release`. It prompts a list for There are two kinds of publishing setups, both performed by `nr release`. -
+
#### Build Locally @@ -161,7 +143,7 @@ In `package.json`, we usually have: So whenever you run `npm publish`, it will make sure you have the latest change in the distribution. - + #### Build on CI @@ -177,38 +159,41 @@ Changelogs are always generated by GitHub Actions. ## 📖 References -### ESLint +### Lint -We use [ESLint](https://eslint.org/) for both linting and formatting with [`antfu/eslint-config`](https://github.com/antfu/eslint-config). +We use [Biome](https://biomejs.dev/) for both linting and formatting with [a few custom rules](./biome.json). It is an ultra-fast, Rust based linter and formatter. -
+
#### IDE Setup -We recommend using [VS Code](https://code.visualstudio.com/) along with the [ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint). +We recommend using [VS Code](https://code.visualstudio.com/) along with the [Biome extension](https://marketplace.visualstudio.com/items?itemName=biomejs.biome). With the settings on the right, you can have auto fix and formatting when you save the code you are editing. -
+

VS Code's `settings.json` ```json { + "editor.defaultFormatter": "biomejs.biome", + "editor.formatOnSave": true, "editor.codeActionsOnSave": { - "source.fixAll": false, - "source.fixAll.eslint": true + "quickfix.biome": true } } ```
-### ⚠️ No Prettier - -Since ESLint is already configured to format the code, there is no need to duplicate the functionality with Prettier ([*Why I don't Use Prettier*](https://antfu.me/posts/why-not-prettier)). To format the code, you can run `nr lint --fix` or referring the [ESLint section](#eslint) for IDE Setup. +### No Prettier -If you have Prettier installed in your editor, we recommend you disable it when working on the project to avoid conflict. +> [!WARNING] +> Since ESLint is already configured to format the code, there is no need to duplicate the functionality with Prettier ([*Why I don't Use Prettier*](https://antfu.me/posts/why-not-prettier)). To format the code, you can run `bun lint --apply` or refer to the [Lint section](#lint) for IDE Setup. +> +> If you have Prettier installed in your editor, we recommend you disable it when working on the project to avoid conflict. +> Instead, you may use the [Biome VS Code extension](https://marketplace.visualstudio.com/items?itemName=biomejs.biome). ## 🗒 Additional Info @@ -226,17 +211,3 @@ In case you are interested in, here are some interesting tools, many of which in - [esno](https://github.com/antfu/esno) - TypeScript runner - [taze](https://github.com/antfu/taze) - dependency updater - [bumpp](https://github.com/antfu/bumpp) - version bumpper - -In addition of `ni`, here is a few shell aliases to be even lazier: - -```bash -alias d="nr dev" -alias b="nr build" -alias t="nr test" -alias tu="nr test -u" -alias p="nr play" -alias c="nr typecheck" -alias lint="nr lint" -alias lintf="nr lint --fix" -alias release="nr release" -``` \ No newline at end of file diff --git a/bun.lockb b/bun.lockb index e90ad2628516d7628007ff6274916c81abdf2fae..1202caabc3b30072a8c46820e6905e8505f93ac9 100755 GIT binary patch delta 25113 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

wt!+6f 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 Onu_yd$J|E$@_zs!F`dK! delta 11944 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 diff --git a/db/config.ts b/db/config.ts index 83dda5b..1ed4651 100644 --- a/db/config.ts +++ b/db/config.ts @@ -1,18 +1,18 @@ -import type { Config } from "drizzle-kit"; +import type { Config } from 'drizzle-kit'; export const dbCredentials = { - host: process.env.POSTGRES_HOST || "0.0.0.0", - port: parseInt(process.env.POSTGRES_PORT || '5432'), - user: process.env.POSTGRES_USER || "postgres", - password: process.env.POSTGRES_PASSWORD || "postgres", - database: process.env.POSTGRES_DB || "medium" -} + host: process.env.POSTGRES_HOST || '0.0.0.0', + port: parseInt(process.env.POSTGRES_PORT || '5432'), + user: process.env.POSTGRES_USER || 'postgres', + password: process.env.POSTGRES_PASSWORD || 'postgres', + database: process.env.POSTGRES_DB || 'medium', +}; export const dbCredentialsString = `postgres://${dbCredentials.user}:${dbCredentials.password}@${dbCredentials.host}:${dbCredentials.port}/${dbCredentials.database}`; export default { - out: "./src/db/migrations", - schema: "**/*.schema.ts", - breakpoints: false, - driver: "pg", - dbCredentials + out: './src/db/migrations', + schema: '**/*.schema.ts', + breakpoints: false, + driver: 'pg', + dbCredentials, } satisfies Config; diff --git a/db/migrations/meta/0000_snapshot.json b/db/migrations/meta/0000_snapshot.json index 7c09e13..354ebd1 100644 --- a/db/migrations/meta/0000_snapshot.json +++ b/db/migrations/meta/0000_snapshot.json @@ -72,4 +72,4 @@ "tables": {}, "columns": {} } -} \ No newline at end of file +} diff --git a/db/migrations/meta/_journal.json b/db/migrations/meta/_journal.json index 31eae40..51409b4 100644 --- a/db/migrations/meta/_journal.json +++ b/db/migrations/meta/_journal.json @@ -10,4 +10,4 @@ "breakpoints": false } ] -} \ No newline at end of file +} diff --git a/db/migrations/migrate.ts b/db/migrations/migrate.ts index 49ffe7b..8448dd3 100644 --- a/db/migrations/migrate.ts +++ b/db/migrations/migrate.ts @@ -1,5 +1,7 @@ -import {drizzle} from "drizzle-orm/postgres-js"; -import {migrate} from "drizzle-orm/postgres-js/migrator"; -import {migrationClient} from "@/database.providers"; +import { drizzle } from 'drizzle-orm/postgres-js'; +import { migrate } from 'drizzle-orm/postgres-js/migrator'; +import { migrationClient } from '@/database.providers'; -await migrate(drizzle(migrationClient), {migrationsFolder: `${import.meta.dir}`}); +await migrate(drizzle(migrationClient), { + migrationsFolder: `${import.meta.dir}`, +}); diff --git a/db/seed.ts b/db/seed.ts index 01c482c..5d17cbc 100644 --- a/db/seed.ts +++ b/db/seed.ts @@ -1,20 +1,20 @@ import { exit } from 'process'; import { db } from '@/database.providers'; -import {users} from "@/users/users.schema"; +import { users } from '@/users/users.schema'; const data = { - id: users.id.default, - email: 'test@email.com', - username: 'test', - password: 'test', - bio: 'test', - image: 'test', -} -console.log("Inserting user: ", data) -await db.insert(users).values(data) -console.log("User inserted") + id: users.id.default, + email: 'test@email.com', + username: 'test', + password: 'test', + bio: 'test', + image: 'test', +}; +console.log('Inserting user: ', data); +await db.insert(users).values(data); +console.log('User inserted'); const userResult = await db.select().from(users); -console.log("User result: ", userResult); +console.log('User result: ', userResult); exit(0); diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 7bbc6bc..045ab89 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -1,14 +1,14 @@ -import { defineConfig } from 'vitepress' +import { defineConfig } from 'vitepress'; // https://vitepress.dev/reference/site-config export default defineConfig({ - title: "RealWorld Elysia Docs", - description: "A Vite Press docs of Real World", + title: 'RealWorld Elysia Docs', + description: 'A Vite Press docs of Real World', themeConfig: { // https://vitepress.dev/reference/default-theme-config nav: [ { text: 'Home', link: '/' }, - { text: 'Examples', link: '/markdown-examples' } + { text: 'Examples', link: '/markdown-examples' }, ], sidebar: [ @@ -16,13 +16,13 @@ export default defineConfig({ text: 'Examples', items: [ { text: 'Markdown Examples', link: '/markdown-examples' }, - { text: 'Runtime API Examples', link: '/api-examples' } - ] - } + { text: 'Runtime API Examples', link: '/api-examples' }, + ], + }, ], socialLinks: [ - { icon: 'github', link: 'https://github.com/vuejs/vitepress' } - ] - } -}) + { icon: 'github', link: 'https://github.com/vuejs/vitepress' }, + ], + }, +}); diff --git a/package.json b/package.json index 83bd439..4b7d7c4 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,9 @@ "start": "bun run src/main.ts", "dev": "bun run --watch src/main.ts", "test": "echo \"Error: no test specified\" && exit 1", - "docs:dev": "vitepress dev docs", + "format": "biome format --write .", + "lint": "biome lint .", + "docs": "vitepress dev docs", "docs:build": "vitepress build docs", "docs:preview": "vitepress preview docs", "db:up": "./scripts/create-start-container-with-env.sh", @@ -13,7 +15,8 @@ "db:migrate": "bun run db/migrations/migrate.ts", "db:push": "bun drizzle-kit push:pg --config=db/config.ts", "db:seed": "bun run db/seed.ts", - "db:studio": "bun drizzle-kit studio --config=db/config.ts" + "db:studio": "bun drizzle-kit studio --config=db/config.ts", + "prepare": "husky install" }, "dependencies": { "drizzle-orm": "^0.28.6", @@ -22,8 +25,11 @@ "postgres": "^3.3.5" }, "devDependencies": { + "@biomejs/biome": "1.2.2", "bun-types": "latest", "drizzle-kit": "^0.19.13", + "husky": "^8.0.3", + "lint-staged": "^14.0.1", "pg": "^8.11.3", "vitepress": "^1.0.0-rc.15" }, @@ -31,5 +37,9 @@ "typescript": "^5.0.0" }, "module": "src/index.ts", - "type": "module" + "type": "module", + "lint-staged": { + "*": "biome format --write", + "*.ts": "biome lint --apply" + } } diff --git a/renovate.json b/renovate.json index a6f8372..a325100 100644 --- a/renovate.json +++ b/renovate.json @@ -1,13 +1,8 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:base", - ":disableDependencyDashboard" - ], + "extends": ["config:base", ":disableDependencyDashboard"], "vulnerabilityAlerts": { "automerge": true, - "labels": [ - "security" - ] + "labels": ["security"] } -} \ No newline at end of file +} diff --git a/src/app.module.ts b/src/app.module.ts index c294f51..01bc8e0 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,8 +1,8 @@ // the file name is in the spirit of NestJS, where app module is the device in charge of putting together all the pieces of the app // see: https://docs.nestjs.com/modules -import { Elysia } from "elysia"; -import { usersPlugin } from "./users/users.plugin"; +import { Elysia } from 'elysia'; +import { usersPlugin } from './users/users.plugin'; /** * Add all plugins to the app @@ -10,5 +10,5 @@ import { usersPlugin } from "./users/users.plugin"; export const setupApp = () => { return new Elysia() .use(usersPlugin) - .post("/", ({ store }) => store.usersService.findAll()); + .post('/', ({ store }) => store.usersService.findAll()); }; diff --git a/src/database.providers.ts b/src/database.providers.ts index 6d94c51..bab3f20 100644 --- a/src/database.providers.ts +++ b/src/database.providers.ts @@ -1,6 +1,6 @@ -import { drizzle, PostgresJsDatabase } from "drizzle-orm/postgres-js"; -import postgres from "postgres"; -import { dbCredentialsString } from "@db/config"; +import { dbCredentialsString } from '@db/config'; +import { PostgresJsDatabase, drizzle } from 'drizzle-orm/postgres-js'; +import postgres from 'postgres'; // for migrations export const migrationClient = postgres(dbCredentialsString, { max: 1 }); diff --git a/src/main.ts b/src/main.ts index 0ff9bad..917a78b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,8 +1,8 @@ -import { Elysia } from "elysia"; -import { setupApp } from "@/app.module"; +import { setupApp } from '@/app.module'; +import { Elysia } from 'elysia'; -const app = new Elysia({ prefix: "/api" }).use(setupApp).listen(3000); +const app = new Elysia({ prefix: '/api' }).use(setupApp).listen(3000); console.log( - `🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}` + `🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`, ); diff --git a/src/users/users.module.ts b/src/users/users.module.ts index fc33177..2a592d9 100644 --- a/src/users/users.module.ts +++ b/src/users/users.module.ts @@ -1,7 +1,7 @@ -import { Elysia } from "elysia"; -import { UsersService } from "@/users/users.service"; -import { UsersRepository } from "@/users/users.repository"; -import { db } from "@/database.providers"; +import { db } from '@/database.providers'; +import { UsersRepository } from '@/users/users.repository'; +import { UsersService } from '@/users/users.service'; +import { Elysia } from 'elysia'; export const setupUsers = () => { const usersRepository = new UsersRepository(db); diff --git a/src/users/users.plugin.ts b/src/users/users.plugin.ts index 9a0e869..b07d442 100644 --- a/src/users/users.plugin.ts +++ b/src/users/users.plugin.ts @@ -1,7 +1,7 @@ -import { Elysia } from "elysia"; -import { setupUsers } from "@/users/users.module"; +import { setupUsers } from '@/users/users.module'; +import { Elysia } from 'elysia'; -export const usersPlugin = new Elysia({ prefix: "/users" }) +export const usersPlugin = new Elysia({ prefix: '/users' }) .use(setupUsers) - .post("/", ({ store }) => store.usersService.findAll()) - .post("/login", ({ store }) => store.usersService.findAll()); + .post('/', ({ store }) => store.usersService.findAll()) + .post('/login', ({ store }) => store.usersService.findAll()); diff --git a/src/users/users.repository.ts b/src/users/users.repository.ts index 5404b02..16048f5 100644 --- a/src/users/users.repository.ts +++ b/src/users/users.repository.ts @@ -1,8 +1,8 @@ // users.repository.ts // in charge of database interactions -import { users } from "./users.schema"; -import { PostgresJsDatabase } from "drizzle-orm/postgres-js"; +import { PostgresJsDatabase } from 'drizzle-orm/postgres-js'; +import { users } from './users.schema'; export class UsersRepository { // the type here is diff --git a/src/users/users.schema.ts b/src/users/users.schema.ts index bade696..aea35d3 100644 --- a/src/users/users.schema.ts +++ b/src/users/users.schema.ts @@ -1,25 +1,25 @@ -import { sql } from "drizzle-orm"; -import { pgTable, text, date, serial } from "drizzle-orm/pg-core"; -import { createInsertSchema, createSelectSchema } from "drizzle-typebox"; -import { Type } from "@sinclair/typebox"; +import { Type } from '@sinclair/typebox'; +import { sql } from 'drizzle-orm'; +import { date, pgTable, serial, text } from 'drizzle-orm/pg-core'; +import { createInsertSchema, createSelectSchema } from 'drizzle-typebox'; -export const users = pgTable("users", { - id: serial("id").primaryKey(), - email: text("email").notNull(), - bio: text("bio").notNull(), - image: text("image").notNull(), - password: text("password").notNull(), - username: text("username").notNull(), - created_at: date("created_at").default(sql`CURRENT_DATE`), - updated_at: date("updated_at").default(sql`CURRENT_DATE`), +export const users = pgTable('users', { + id: serial('id').primaryKey(), + email: text('email').notNull(), + bio: text('bio').notNull(), + image: text('image').notNull(), + password: text('password').notNull(), + username: text('username').notNull(), + created_at: date('created_at').default(sql`CURRENT_DATE`), + updated_at: date('updated_at').default(sql`CURRENT_DATE`), }); // Schema for inserting a user - can be used to validate API requests const insertUserSchemaRaw = createInsertSchema(users); export const insertUserSchema = Type.Omit(insertUserSchemaRaw, [ - "id", - "created_at", - "updated_at", + 'id', + 'created_at', + 'updated_at', ]); // Schema for selecting a user - can be used to validate API responses diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 038b11b..2e9bede 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -1,7 +1,7 @@ // users.service.ts // in charge of business logic - generate slug, fetch data from other services, cache something, etc. -import { UsersRepository } from "@/users/users.repository"; +import { UsersRepository } from '@/users/users.repository'; export class UsersService { constructor(private readonly repository: UsersRepository) {}