Skip to content

Commit

Permalink
Merge pull request #156 from ixartz/turso-drizzle
Browse files Browse the repository at this point in the history
Add Turso and Drizzle ORM
  • Loading branch information
ixartz committed Aug 24, 2023
2 parents 0e26234 + ea4a5c1 commit ebf6d01
Show file tree
Hide file tree
Showing 30 changed files with 8,004 additions and 4,296 deletions.
15 changes: 15 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Configure environment variables

# Database
# Please use a working DATABASE_URL. Otherwise, Next.js build will timeout and you will get the following error: "because it took more than 60 seconds"
# DATABASE_URL=libsql://[RANDOM-CHARS]-[DB-NAME]-[ORG-NAME].turso.io
DATABASE_URL=file:next-js-boilerplate.db

# Clerk authentication
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_bGlnaHQtbGFicmFkb3ItNTEuY2xlcmsuYWNjb3VudHMuZGV2JA
CLERK_SECRET_KEY=your_clerk_secret_key

NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/dashboard
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/dashboard
7 changes: 0 additions & 7 deletions .env.development

This file was deleted.

1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"endOfLine": "auto"
}
],
"import/extensions": "off", // Avoid missing file extension errors, TypeScript already provides a similar feature
"react/function-component-definition": "off", // Disable Airbnb's specific function type
"react/destructuring-assignment": "off", // Vscode doesn't support automatically destructuring, it's a pain to add a new variable
"react/require-default-props": "off", // Allow non-defined react props as undefined
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
node-version: ${{ matrix.node-version }}
cache: "npm"
- run: npm ci
- run: npm run build-prod
- run: npm run build

test:
strategy:
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,4 @@ jobs:
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-release
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
/.pnp
.pnp.js

# Database
*.db

# testing
/coverage

Expand Down
55 changes: 50 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<a href="https://creativedesignsguru.com/demo/Nextjs-Boilerplate/"><img height="300" src="public/assets/images/nextjs-starter-banner.png?raw=true" alt="Next js starter banner"></a>
</p>

🚀 Boilerplate and Starter for Next.js with App Router and Page Router support, Tailwind CSS and TypeScript ⚡️ Made with developer experience first: Next.js, TypeScript, ESLint, Prettier, Husky, Lint-Staged, Jest, Testing Library, Commitlint, VSCode, Netlify, PostCSS, Tailwind CSS, Authentication with [Clerk](https://clerk.com?utm_source=github&utm_medium=sponsorship&utm_campaign=nextjs-boilerplate).
🚀 Boilerplate and Starter for Next.js with App Router and Page Router support, Tailwind CSS and TypeScript ⚡️ Made with developer experience first: Next.js, TypeScript, ESLint, Prettier, Husky, Lint-Staged, Jest, Testing Library, Commitlint, VSCode, Netlify, PostCSS, Tailwind CSS, Authentication with [Clerk](https://clerk.com?utm_source=github&utm_medium=sponsorship&utm_campaign=nextjs-boilerplate), Database with DrizzleORM (SQLite, PostgreSQL, and MySQL) and [Turso](https://turso.tech/?utm_source=nextjsstarterbp)

Clone this project and use it to create your own [Next.js](https://nextjs.org) project. You can check a [Next js templates demo](https://creativedesignsguru.com/demo/Nextjs-Boilerplate/).

Expand Down Expand Up @@ -49,6 +49,12 @@ Developer experience first:
- 🔥 Type checking [TypeScript](https://www.typescriptlang.org)
- 💎 Integrate with [Tailwind CSS](https://tailwindcss.com)
- ✅ Strict Mode for TypeScript and React 18
- 🔒 Authentication with [Clerk](https://clerk.com?utm_source=github&utm_medium=sponsorship&utm_campaign=nextjs-boilerplate): Sign up, Sign in, Sign out, Forgot password, Reset password, and more.
- 📦 Type-safe ORM with DrizzleORM, compatible with SQLite, PostgreSQL, and MySQL
- 💽 Global Database with [Turso](https://turso.tech/?utm_source=nextjsstarterbp)
- ♻️ Type-safe environment variables with T3 Env
- ⌨️ Form with React Hook From
- 🔴 Validation library with Zod
- 📏 Linter with [ESLint](https://eslint.org) (default NextJS, NextJS Core Web Vitals, Tailwind CSS and Airbnb configuration)
- 💖 Code Formatter with [Prettier](https://prettier.io)
- 🦊 Husky for Git Hooks
Expand All @@ -62,10 +68,10 @@ Developer experience first:
- 🎁 Automatic changelog generation with Semantic Release
- 🔍 Visual testing with Percy (Optional)
- 💡 Absolute Imports using `@` prefix
- 🔒 Authentication with [Clerk](https://clerk.com?utm_source=github&utm_medium=sponsorship&utm_campaign=nextjs-boilerplate): Sign up, Sign in, Sign out, Forgot password, Reset password, and more.
- 🗂 VSCode configuration: Debug, Settings, Tasks and extension for PostCSS, ESLint, Prettier, TypeScript, Jest
- 🤖 SEO metadata, JSON-LD and Open Graph tags with Next SEO
- 🗺️ Sitemap.xml and robots.txt with next-sitemap
- ⌘ Database exploration with Drizzle Studio and CLI migration tool with Drizzle Kit
- ⚙️ [Bundler Analyzer](https://www.npmjs.com/package/@next/bundle-analyzer)
- 🖱️ One click deployment with Vercel or Netlify (or manual deployment to any hosting services)
- 🌈 Include a FREE minimalist theme
Expand Down Expand Up @@ -109,7 +115,7 @@ Open http://localhost:3000 with your favorite browser to see your project.

### Set up authentication

Create a Clerk account at [Clerk.com](https://clerk.com?utm_source=github&utm_medium=sponsorship&utm_campaign=nextjs-boilerplate) and create a new application in Clerk Dashboard. Then, copy `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY` into `.env.development.local` file:
Create a Clerk account at [Clerk.com](https://clerk.com?utm_source=github&utm_medium=sponsorship&utm_campaign=nextjs-boilerplate) and create a new application in Clerk Dashboard. Then, copy `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY` into `.env.local` file (not tracked by Git):

```shell
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_clerk_pub_key
Expand All @@ -118,6 +124,41 @@ CLERK_SECRET_KEY=your_clerk_secret_key

Now, you can a fully working authentication system with Next.js: Sign up, Sign in, Sign out, Forgot password, Reset password, Update profile, Update password, Update email, Delete account, and more.

### Set up remote database

The project uses DrizzleORM, a type-safe ORM compatible with SQLite, PostgreSQL, and MySQL databases. By default, the project is set up to work seamlessly with libSQL, and for production purposes, it's integrated with [Turso](https://turso.tech/?utm_source=nextjsstarterbp). The Next.js Boilerplate also enables a smooth transition to an alternative database provider if your project requires it.

First, you need to create a Turso account at [Turso.tech](https://turso.tech/?utm_source=nextjsstarterbp) and install the Turso CLI:

```shell
brew install tursodatabase/tap/turso
turso auth signup # Sign up to Turso
```

Then, create a new database:

```shell
turso db create nextjs-boilerplate
```

Now, you need to update the `DATABASE_URL` in `.env` file with the database URL provided by Turso:

```shell
turso db show nextjs-boilerplate --url

# .env
# DATABASE_URL=libsql://[RANDOM-CHARS]-[DB-NAME]-[ORG-NAME].turso.io
```

Finally, you also need to create a new environement variable `DATABASE_AUTH_TOKEN` in `.env.local` (not tracked by Git) with the auth token provided by Turso:

```shell
turso db tokens create nextjs-boilerplate

# .env.local
# DATABASE_AUTH_TOKEN=[your-auth-token]
```

### Project structure

```shell
Expand All @@ -129,12 +170,16 @@ Now, you can a fully working authentication system with Next.js: Sign up, Sign i
├── .vscode # VSCode configuration
├── public # Public assets folder
├── src
│ ├── layouts # Layouts components
│ ├── app # Next JS Pages (app router)
│ ├── components # React components
│ ├── layouts # Layouts components
│ ├── libs # 3rd party libraries
│ ├── models # Database models
│ ├── pages # Next JS Pages (page router)
│ ├── pages.test # Next JS Pages tests (this avoids tests to be treated as a Next.js pages)
│ ├── styles # Styles folder
│ ├── templates # Default template
│ ├── validations # Validation schemas
│ └── utils # Utility functions
├── tailwind.config.js # Tailwind CSS configuration
└── tsconfig.json # TypeScript configuration
Expand Down Expand Up @@ -176,7 +221,7 @@ The generated HTML and CSS files are minified (built-in feature from Next js). I
You can create an optimized production build with:

```shell
npm run build-prod
npm run build
```

Now, your blog is ready to be deployed. All generated files are located at `out` folder, which you can deploy with any hosting service.
Expand Down
16 changes: 16 additions & 0 deletions drizzle.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* eslint-disable-next-line import/no-extraneous-dependencies */
import dotenv from 'dotenv';
import type { Config } from 'drizzle-kit';

dotenv.config({
path: '.env',
});

export default {
out: './migrations',
schema: './src/models/schema.ts',
driver: 'libsql',
dbCredentials: {
url: process.env.DATABASE_URL ?? '',
},
} satisfies Config;
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const customJestConfig = {

'^__mocks__/(.*)$': '<rootDir>/__mocks__/$1',
},
setupFilesAfterEnv: ['./jest.setup.ts'],
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
clearMocks: true,
collectCoverage: true,
collectCoverageFrom: [
Expand Down
2 changes: 1 addition & 1 deletion jest.setup.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// Optional: configure or set up a testing framework before each test.
// If you delete this file, remove `setupFilesAfterEnv` from `jest.config.js`
import '@testing-library/jest-dom/extend-expect';
import '@testing-library/jest-dom';
7 changes: 7 additions & 0 deletions migrations/0000_sharp_marten_broadcloak.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TABLE `guestbook` (
`id` integer PRIMARY KEY NOT NULL,
`username` text NOT NULL,
`body` text NOT NULL,
`created_at` integer DEFAULT (strftime('%s', 'now')),
`updated_at` integer DEFAULT (strftime('%s', 'now'))
);
60 changes: 60 additions & 0 deletions migrations/meta/0000_snapshot.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"version": "5",
"dialect": "sqlite",
"id": "33ba2aeb-9902-4f71-9e40-f18012cd5d31",
"prevId": "00000000-0000-0000-0000-000000000000",
"tables": {
"guestbook": {
"name": "guestbook",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"username": {
"name": "username",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"body": {
"name": "body",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": "(strftime('%s', 'now'))"
},
"updated_at": {
"name": "updated_at",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": "(strftime('%s', 'now'))"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
}
},
"enums": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
}
}
13 changes: 13 additions & 0 deletions migrations/meta/_journal.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": "5",
"dialect": "sqlite",
"entries": [
{
"idx": 0,
"version": "5",
"when": 1692483682335,
"tag": "0000_sharp_marten_broadcloak",
"breakpoints": true
}
]
}
16 changes: 0 additions & 16 deletions next.config.js

This file was deleted.

31 changes: 31 additions & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* eslint-disable import/no-extraneous-dependencies, import/extensions */
import './src/libs/Env.mjs';
import withBundleAnalyzer from '@next/bundle-analyzer';

const bundleAnalyzer = withBundleAnalyzer({
enabled: process.env.ANALYZE === 'true',
});

/** @type {import('next').NextConfig} */
export default bundleAnalyzer({
eslint: {
dirs: ['.'],
},
poweredByHeader: false,
basePath: '',
// The starter code load resources from `public` folder with `router.basePath` in React components.
// So, the source code is "basePath-ready".
// You can remove `basePath` if you don't need it.
reactStrictMode: true,
webpack: (config) => {
// config.externals is needed to resolve the following errors:
// Module not found: Can't resolve 'bufferutil'
// Module not found: Can't resolve 'utf-8-validate'
config.externals.push({
bufferutil: 'bufferutil',
'utf-8-validate': 'utf-8-validate',
});

return config;
},
});
Loading

0 comments on commit ebf6d01

Please sign in to comment.