Skip to content

Commit 6f10381

Browse files
committed
feat!: Replace eslint & prettier to biome
1 parent f572038 commit 6f10381

File tree

235 files changed

+1701
-4051
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

235 files changed

+1701
-4051
lines changed

.github/copilot-instructions.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
The repository is a monorepo for the VitNode framework, which includes a backend API, frontend documentation site, and shared packages. The codebase uses modern web technologies and follows specific conventions for development based on Next.js 15 and Hono.js 4.
44

5+
- Do not nest ternary operators,
6+
57
## Architecture & Key Patterns
68

79
- **Monorepo Structure:**
810
- `apps/` contains main apps (`api` for backend, `docs` for docs site)
9-
- `packages/` holds shared code, core framework, ESLint/Prettier configs, and CLI tools
11+
- `packages/` holds shared code, core framework, Biome configs, and CLI tools
1012
- `plugins/` for extendable features
1113
- **Frontend:**
1214
- Next.js 15, App Router, Server Components
@@ -33,7 +35,7 @@ The repository is a monorepo for the VitNode framework, which includes a backend
3335
- `pnpm dev` (dev server), `pnpm build`, `pnpm lint`, `pnpm db:push`, `pnpm db:migrate`, `pnpm docker:dev`
3436
- **CLI:**
3537
- Create apps/plugins via `pnpm create vitnode-app@canary` (see `packages/create-vitnode-app`)
36-
- CLI prompts for package manager, app mode, ESLint, Docker, install (see `questions.ts`)
38+
- CLI prompts for package manager, app mode, Biome, Docker, install (see `questions.ts`)
3739
- **Linting/Formatting:**
3840
- Use configs from `packages/eslint/`
3941
- File names: snake_case, ESModule only

.github/docs/prd.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ VitNode is designed for individual developers and small teams who need a structu
4646
### CI/CD
4747

4848
- Automated workflows using GitHub Actions:
49-
- Code quality checks (ESLint, Prettier, TypeScript)
49+
- Code quality checks (Biome, TypeScript)
5050
- Test suite execution with Vitest and Playwright
5151
- Dependency security scanning with npm audit
5252
- Automated builds and deployments to Vercel
@@ -165,7 +165,7 @@ VitNode is designed for individual developers and small teams who need a structu
165165
- Turborepo for monorepo management
166166
- Vitest for unit testing
167167
- Playwright for end-to-end testing
168-
- ESLint and Prettier for code quality
168+
- Biome for code quality
169169
- Docker for containerization
170170

171171
## Features Planned for Future Releases

.prettierrc.mjs

Lines changed: 0 additions & 11 deletions
This file was deleted.

.vscode/settings.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,29 @@
77
],
88
"search.exclude": {
99
"**/(plugins)/*": true
10+
},
11+
"[javascriptreact]": {
12+
"editor.defaultFormatter": "biomejs.biome"
13+
},
14+
"[typescript]": {
15+
"editor.defaultFormatter": "biomejs.biome"
16+
},
17+
"[css]": {
18+
"editor.defaultFormatter": "biomejs.biome"
19+
},
20+
"[jsonc]": {
21+
"editor.defaultFormatter": "biomejs.biome"
22+
},
23+
"[typescriptreact]": {
24+
"editor.defaultFormatter": "biomejs.biome"
25+
},
26+
"[html]": {
27+
"editor.defaultFormatter": "biomejs.biome"
28+
},
29+
"[json]": {
30+
"editor.defaultFormatter": "biomejs.biome"
31+
},
32+
"[javascript]": {
33+
"editor.defaultFormatter": "biomejs.biome"
1034
}
1135
}

apps/api/eslint.config.mjs

Lines changed: 0 additions & 20 deletions
This file was deleted.

apps/api/package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
"dev:email": "email dev --dir src/emails",
1212
"build": "tsc && tsc-alias -p tsconfig.json",
1313
"start": "node dist/index.js",
14-
"lint": "eslint .",
15-
"lint:fix": "eslint . --fix",
1614
"drizzle-kit": "drizzle-kit"
1715
},
1816
"dependencies": {
@@ -36,7 +34,6 @@
3634
"@types/react-dom": "^19.1.7",
3735
"@vitnode/eslint-config": "workspace:*",
3836
"dotenv": "^17.2.1",
39-
"eslint": "^9.33.0",
4037
"react-email": "^4.2.8",
4138
"tsc-alias": "^1.8.16",
4239
"tsx": "^4.20.4",

apps/api/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ serve(
1919
info => {
2020
const initMessage = '\x1b[34m[VitNode]\x1b[0m';
2121

22-
// eslint-disable-next-line no-console
22+
// biome-ignore lint/suspicious/noConsole: <start>
2323
console.log(
2424
`${initMessage} API server is running on http://localhost:${info.port}`,
2525
);

apps/api/src/vitnode.api.config.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import { NodemailerEmailAdapter } from '@vitnode/core/api/adapters/email/nodemailer';
22
import { buildApiConfig } from '@vitnode/core/vitnode.config';
3-
import * as dotenv from 'dotenv';
3+
import { config } from 'dotenv';
44
import { drizzle } from 'drizzle-orm/postgres-js';
55

6-
dotenv.config({
6+
config({
77
quiet: true,
88
});
99

1010
export const POSTGRES_URL =
11-
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
1211
process.env.POSTGRES_URL || 'postgresql://root:root@localhost:5432/vitnode';
1312

1413
export const vitNodeApiConfig = buildApiConfig({

apps/docs/content/docs/ui/combobox.mdx

Lines changed: 58 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,20 @@ description: Select from a list of options with a search input.
99

1010
## Usage
1111

12-
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
12+
import { Tab, Tabs } from "fumadocs-ui/components/tabs";
1313

1414
<Tabs items={['Auto Form', 'Manual']}>
1515
<Tab value="Auto Form">
1616

1717
```ts
18-
import { z } from 'zod';
19-
import { AutoForm } from '@vitnode/core/components/form/auto-form';
20-
import { AutoFormCombobox } from '@vitnode/core/components/form/fields/combobox';
18+
import { z } from "zod";
19+
import { AutoForm } from "@vitnode/core/components/form/auto-form";
20+
import { AutoFormCombobox } from "@vitnode/core/components/form/fields/combobox";
2121
```
2222

2323
```ts
2424
const formSchema = z.object({
25-
type: z.enum(['option-one', 'option-two']),
25+
type: z.enum(["option-one", "option-two"])
2626
});
2727
```
2828

@@ -31,25 +31,25 @@ const formSchema = z.object({
3131
formSchema={formSchema}
3232
fields={[
3333
{
34-
id: 'type',
35-
component: props => (
34+
id: "type",
35+
component: (props) => (
3636
<AutoFormCombobox
3737
{...props}
3838
description="Select an option from the list"
3939
label="Type"
4040
labels={[
4141
{
42-
value: 'option-one',
43-
label: 'Option One',
42+
value: "option-one",
43+
label: "Option One"
4444
},
4545
{
46-
value: 'option-two',
47-
label: 'Option Two',
48-
},
46+
value: "option-two",
47+
label: "Option Two"
48+
}
4949
]}
5050
/>
51-
),
52-
},
51+
)
52+
}
5353
]}
5454
/>
5555
```
@@ -59,53 +59,49 @@ const formSchema = z.object({
5959
<Tab value="Manual">
6060

6161
```tsx
62-
'use client';
62+
"use client";
6363

64-
import * as React from 'react';
65-
import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react';
64+
import React from "react";
65+
import { CheckIcon, ChevronsUpDownIcon } from "lucide-react";
6666

67-
import { cn } from '@vitnode/core/lib/utils';
68-
import { Button } from '@vitnode/core/components/ui/button';
67+
import { cn } from "@vitnode/core/lib/utils";
68+
import { Button } from "@vitnode/core/components/ui/button";
6969
import {
7070
Command,
7171
CommandEmpty,
7272
CommandGroup,
7373
CommandInput,
7474
CommandItem,
75-
CommandList,
76-
} from '@vitnode/core/components/ui/command';
77-
import {
78-
Popover,
79-
PopoverContent,
80-
PopoverTrigger,
81-
} from '@vitnode/core/components/ui/popover';
75+
CommandList
76+
} from "@vitnode/core/components/ui/command";
77+
import { Popover, PopoverContent, PopoverTrigger } from "@vitnode/core/components/ui/popover";
8278

8379
const frameworks = [
8480
{
85-
value: 'next.js',
86-
label: 'Next.js',
81+
value: "next.js",
82+
label: "Next.js"
8783
},
8884
{
89-
value: 'sveltekit',
90-
label: 'SvelteKit',
85+
value: "sveltekit",
86+
label: "SvelteKit"
9187
},
9288
{
93-
value: 'nuxt.js',
94-
label: 'Nuxt.js',
89+
value: "nuxt.js",
90+
label: "Nuxt.js"
9591
},
9692
{
97-
value: 'remix',
98-
label: 'Remix',
93+
value: "remix",
94+
label: "Remix"
9995
},
10096
{
101-
value: 'astro',
102-
label: 'Astro',
103-
},
97+
value: "astro",
98+
label: "Astro"
99+
}
104100
];
105101

106102
export function ExampleCombobox() {
107103
const [open, setOpen] = React.useState(false);
108-
const [value, setValue] = React.useState('');
104+
const [value, setValue] = React.useState("");
109105

110106
return (
111107
<Popover open={open} onOpenChange={setOpen}>
@@ -117,8 +113,8 @@ export function ExampleCombobox() {
117113
className="w-[200px] justify-between"
118114
>
119115
{value
120-
? frameworks.find(framework => framework.value === value)?.label
121-
: 'Select framework...'}
116+
? frameworks.find((framework) => framework.value === value)?.label
117+
: "Select framework..."}
122118
<ChevronsUpDownIcon className="ml-2 size-4 shrink-0 opacity-50" />
123119
</Button>
124120
</PopoverTrigger>
@@ -128,19 +124,19 @@ export function ExampleCombobox() {
128124
<CommandList>
129125
<CommandEmpty>No framework found.</CommandEmpty>
130126
<CommandGroup>
131-
{frameworks.map(framework => (
127+
{frameworks.map((framework) => (
132128
<CommandItem
133129
key={framework.value}
134130
value={framework.value}
135-
onSelect={currentValue => {
136-
setValue(currentValue === value ? '' : currentValue);
131+
onSelect={(currentValue) => {
132+
setValue(currentValue === value ? "" : currentValue);
137133
setOpen(false);
138134
}}
139135
>
140136
<CheckIcon
141137
className={cn(
142-
'mr-2 size-4',
143-
value === framework.value ? 'opacity-100' : 'opacity-0',
138+
"mr-2 size-4",
139+
value === framework.value ? "opacity-100" : "opacity-0"
144140
)}
145141
/>
146142
{framework.label}
@@ -161,36 +157,34 @@ export function ExampleCombobox() {
161157

162158
## Props
163159

164-
import { TypeTable } from 'fumadocs-ui/components/type-table';
160+
import { TypeTable } from "fumadocs-ui/components/type-table";
165161

166162
<TypeTable
167163
type={{
168164
label: {
169-
description: 'The label for the combobox, displayed above the input.',
170-
type: 'string',
171-
default: '',
165+
description: "The label for the combobox, displayed above the input.",
166+
type: "string",
167+
default: ""
172168
},
173169
description: {
174-
description:
175-
'An optional description for the combobox, displayed below the input.',
176-
type: 'string',
177-
default: '',
170+
description: "An optional description for the combobox, displayed below the input.",
171+
type: "string",
172+
default: ""
178173
},
179174
labels: {
180-
description:
181-
'An array of options for the combobox, each with a value and label.',
182-
type: 'Array<{ value: string; label: string }>',
183-
default: '[]',
175+
description: "An array of options for the combobox, each with a value and label.",
176+
type: "Array<{ value: string; label: string }>",
177+
default: "[]"
184178
},
185179
placeholder: {
186-
description: 'Placeholder text for the combobox input.',
187-
type: 'string',
188-
default: 'Select an option',
180+
description: "Placeholder text for the combobox input.",
181+
type: "string",
182+
default: "Select an option"
189183
},
190184
searchPlaceholder: {
191-
description: 'Placeholder text for the search input within the combobox.',
192-
type: 'string',
193-
default: 'Search...',
194-
},
185+
description: "Placeholder text for the search input within the combobox.",
186+
type: "string",
187+
default: "Search..."
188+
}
195189
}}
196190
/>

apps/docs/e2e/homepage.spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { expect, test } from '@playwright/test';
22

3+
const vitNodeTitleRegex = /VitNode/;
4+
35
test.describe('Homepage', () => {
46
test('should load successfully', async ({ page }) => {
57
await page.goto('/');
6-
await expect(page).toHaveTitle(/VitNode/);
8+
await expect(page).toHaveTitle(vitNodeTitleRegex);
79
await expect(page.getByText('Start Your Journey!')).toBeVisible();
810
});
911
});

0 commit comments

Comments
 (0)