project setup

This commit is contained in:
Pihkaal
2024-01-11 17:19:37 +01:00
commit 01ed9437fa
22 changed files with 4392 additions and 0 deletions

3
.env.example Normal file
View File

@@ -0,0 +1,3 @@
# Drizzle
DATABASE_URL='mysql://YOUR_MYSQL_URL_HERE?ssl={"rejectUnauthorized":true}'

39
.eslintrc.cjs Normal file
View File

@@ -0,0 +1,39 @@
// @ts-check
/** @type {import("eslint").Linter.Config} */
const config = {
parser: "@typescript-eslint/parser",
parserOptions: {
project: true,
},
plugins: ["@typescript-eslint"],
extends: [
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended-type-checked",
"plugin:@typescript-eslint/stylistic-type-checked",
],
rules: {
// These opinionated rules are enabled in stylistic-type-checked above.
// Feel free to reconfigure them to your own preference.
"@typescript-eslint/array-type": "off",
"@typescript-eslint/consistent-type-definitions": "off",
"@typescript-eslint/consistent-type-imports": [
"warn",
{
prefer: "type-imports",
fixStyle: "inline-type-imports",
},
],
"@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
"@typescript-eslint/require-await": "off",
"@typescript-eslint/no-misused-promises": [
"error",
{
checksVoidReturn: { attributes: false },
},
],
},
};
module.exports = config;

39
.gitignore vendored Normal file
View File

@@ -0,0 +1,39 @@
# Dependencies
/node_modules
/.pnp
.pnp.js
# Testing
/coverage
# Database
/prisma/db.sqlite
/prisma/db.sqlite-journal
# Next.js
/.next/
/out/
next-env.d.ts
# Production
/build
# Misc
.DS_Store
*.pem
# Debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# Local env files
.env
.env*.local
# Vercel
.vercel
# Typescript
*.tsbuildinfo

18
.prettierrc.cjs Normal file
View File

@@ -0,0 +1,18 @@
// @ts-check
/** @type {import("prettier").Options & import("prettier-plugin-tailwindcss").PluginOptions} */
const config = {
plugins: ["prettier-plugin-tailwindcss"],
arrowParens: "avoid",
bracketSpacing: true,
quoteProps: "consistent",
jsxSingleQuote: false,
printWidth: 80,
semi: true,
singleQuote: false,
tabWidth: 2,
trailingComma: "all",
useTabs: false,
};
module.exports = config;

1
README.md Normal file
View File

@@ -0,0 +1 @@
# pihkaal.me

16
drizzle.config.ts Normal file
View File

@@ -0,0 +1,16 @@
// @ts-check
import { type Config } from "drizzle-kit";
import { env } from "~/env";
const config: Config = {
schema: "./src/server/db/schema.ts",
driver: "mysql2",
dbCredentials: {
uri: env.DATABASE_URL,
},
tablesFilter: ["me_*"],
};
export default config;

15
next.config.js Normal file
View File

@@ -0,0 +1,15 @@
// @ts-check
await import("./src/env.js");
/** @type {import("next").NextConfig} */
const config = {
reactStrictMode: true,
i18n: {
locales: ["en"],
defaultLocale: "en",
},
};
export default config;

52
package.json Normal file
View File

@@ -0,0 +1,52 @@
{
"name": "pihkaal.me",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"build": "next build",
"db:push": "drizzle-kit push:mysql",
"db:studio": "drizzle-kit studio",
"dev": "next dev",
"lint": "next lint --cache --fix",
"start": "next start",
"format": "prettier --cache --write '**/*.{md,json,css,scss,js,mjs,cjs,ts,tsx}'"
},
"dependencies": {
"@planetscale/database": "^1.11.0",
"@t3-oss/env-nextjs": "^0.7.1",
"@tanstack/react-query": "^4.36.1",
"@trpc/client": "^10.43.6",
"@trpc/next": "^10.43.6",
"@trpc/react-query": "^10.43.6",
"@trpc/server": "^10.43.6",
"drizzle-orm": "^0.29.3",
"next": "^14.0.4",
"react": "18.2.0",
"react-dom": "18.2.0",
"superjson": "^2.2.1",
"zod": "^3.22.4"
},
"devDependencies": {
"@types/eslint": "^8.44.7",
"@types/node": "^18.17.0",
"@types/react": "^18.2.37",
"@types/react-dom": "^18.2.15",
"@typescript-eslint/eslint-plugin": "^6.11.0",
"@typescript-eslint/parser": "^6.11.0",
"autoprefixer": "^10.4.14",
"drizzle-kit": "^0.20.9",
"eslint": "^8.54.0",
"eslint-config-next": "^14.0.4",
"mysql2": "^3.6.1",
"postcss": "^8.4.31",
"prettier": "^3.1.0",
"prettier-plugin-tailwindcss": "^0.5.11",
"tailwindcss": "^3.3.5",
"typescript": "^5.1.6"
},
"ct3aMetadata": {
"initVersion": "7.25.1"
},
"packageManager": "pnpm@8.14.1"
}

3967
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

10
postcss.config.cjs Normal file
View File

@@ -0,0 +1,10 @@
// @ts-check
const config = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
module.exports = config;

26
src/env.js Normal file
View File

@@ -0,0 +1,26 @@
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";
export const env = createEnv({
server: {
DATABASE_URL: z
.string()
.url()
.refine(
str => !str.includes("YOUR_MYSQL_URL_HERE"),
"You forgot to change the default URL",
),
NODE_ENV: z
.enum(["development", "test", "production"])
.default("development"),
},
client: {},
runtimeEnv: {
DATABASE_URL: process.env.DATABASE_URL,
NODE_ENV: process.env.NODE_ENV,
},
skipValidation: !!process.env.SKIP_ENV_VALIDATION,
emptyStringAsUndefined: true,
});

11
src/pages/_app.tsx Normal file
View File

@@ -0,0 +1,11 @@
import { type AppType } from "next/app";
import { api } from "~/utils/api";
import "~/styles/globals.css";
const MyApp: AppType = ({ Component, pageProps }) => {
return <Component {...pageProps} />;
};
export default api.withTRPC(MyApp);

View File

@@ -0,0 +1,18 @@
import { createNextApiHandler } from "@trpc/server/adapters/next";
import { env } from "~/env";
import { appRouter } from "~/server/api/root";
import { createTRPCContext } from "~/server/api/trpc";
export default createNextApiHandler({
router: appRouter,
createContext: createTRPCContext,
onError:
env.NODE_ENV === "development"
? ({ path, error }) => {
console.error(
`❌ tRPC failed on ${path ?? "<no-path>"}: ${error.message}`,
);
}
: undefined,
});

12
src/pages/index.tsx Normal file
View File

@@ -0,0 +1,12 @@
import Head from "next/head";
export default function Home() {
return (
<>
<Head>
<title>pihkaal</title>
</Head>
<main></main>
</>
);
}

5
src/server/api/root.ts Normal file
View File

@@ -0,0 +1,5 @@
import { createTRPCRouter } from "~/server/api/trpc";
export const appRouter = createTRPCRouter({});
export type AppRouter = typeof appRouter;

48
src/server/api/trpc.ts Normal file
View File

@@ -0,0 +1,48 @@
import { initTRPC } from "@trpc/server";
import { type CreateNextContextOptions } from "@trpc/server/adapters/next";
import superjson from "superjson";
import { ZodError } from "zod";
import { db } from "~/server/db";
/**
* 1. CONTEXT
*/
type CreateContextOptions = Record<string, never>;
const createInnerTRPCContext = (_opts: CreateContextOptions) => {
return {
db,
};
};
export const createTRPCContext = (_opts: CreateNextContextOptions) => {
return createInnerTRPCContext({});
};
/**
* 2. INITIALIZATION
*/
const t = initTRPC.context<typeof createTRPCContext>().create({
transformer: superjson,
errorFormatter({ shape, error }) {
return {
...shape,
data: {
...shape.data,
zodError:
error.cause instanceof ZodError ? error.cause.flatten() : null,
},
};
},
});
/**
* 3. ROUTER & PROCEDURE (THE IMPORTANT BIT)
*/
export const createTRPCRouter = t.router;
export const publicProcedure = t.procedure;

12
src/server/db/index.ts Normal file
View File

@@ -0,0 +1,12 @@
import { Client } from "@planetscale/database";
import { drizzle } from "drizzle-orm/planetscale-serverless";
import { env } from "~/env";
import * as schema from "./schema";
export const db = drizzle(
new Client({
url: env.DATABASE_URL,
}).connection(),
{ schema },
);

3
src/server/db/schema.ts Normal file
View File

@@ -0,0 +1,3 @@
import { mysqlTableCreator } from "drizzle-orm/mysql-core";
export const mysqlTable = mysqlTableCreator(name => `me_${name}`);

3
src/styles/globals.css Normal file
View File

@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

36
src/utils/api.ts Normal file
View File

@@ -0,0 +1,36 @@
import { httpBatchLink, loggerLink } from "@trpc/client";
import { createTRPCNext } from "@trpc/next";
import { type inferRouterInputs, type inferRouterOutputs } from "@trpc/server";
import superjson from "superjson";
import { type AppRouter } from "~/server/api/root";
const getBaseUrl = () => {
if (typeof window !== "undefined") return ""; // browser should use relative url
if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`; // SSR should use vercel url
return `http://localhost:${process.env.PORT ?? 3000}`; // dev SSR should use localhost
};
export const api = createTRPCNext<AppRouter>({
config() {
return {
transformer: superjson,
links: [
loggerLink({
enabled: opts =>
process.env.NODE_ENV === "development" ||
(opts.direction === "down" && opts.result instanceof Error),
}),
httpBatchLink({
url: `${getBaseUrl()}/api/trpc`,
}),
],
};
},
ssr: false,
});
export type RouterInputs = inferRouterInputs<AppRouter>;
export type RouterOutputs = inferRouterOutputs<AppRouter>;

16
tailwind.config.ts Normal file
View File

@@ -0,0 +1,16 @@
import { type Config } from "tailwindcss";
import { fontFamily } from "tailwindcss/defaultTheme";
const config: Config = {
content: ["./src/**/*.tsx"],
theme: {
extend: {
fontFamily: {
sans: ["var(--font-sans)", ...fontFamily.sans],
},
},
},
plugins: [],
};
export default config;

42
tsconfig.json Normal file
View File

@@ -0,0 +1,42 @@
{
"compilerOptions": {
/* Base Options: */
"esModuleInterop": true,
"skipLibCheck": true,
"target": "es2022",
"allowJs": true,
"resolveJsonModule": true,
"moduleDetection": "force",
"isolatedModules": true,
/* Strictness */
"strict": true,
"noUncheckedIndexedAccess": true,
"checkJs": true,
/* Bundled projects */
"lib": ["dom", "dom.iterable", "ES2022"],
"noEmit": true,
"module": "ESNext",
"moduleResolution": "Bundler",
"jsx": "preserve",
"plugins": [{ "name": "next" }],
"incremental": true,
/* Path Aliases */
"baseUrl": ".",
"paths": {
"~/*": ["./src/*"]
}
},
"include": [
".eslintrc.cjs",
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
"**/*.cjs",
"**/*.js",
".next/types/**/*.ts"
],
"exclude": ["node_modules"]
}