#### 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 e90ad26..1202caa 100755
Binary files a/bun.lockb and b/bun.lockb differ
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) {}
|
|