From 163b8bdc52ea487203a3ac4b4fc20d48cace00d0 Mon Sep 17 00:00:00 2001 From: rykuno Date: Sat, 25 May 2024 01:02:33 -0500 Subject: [PATCH] updated readme --- README.md | 75 +++++++++++++------ .../email-verification.handlebars | 0 src/lib/server/api/services/mailer.service.ts | 2 +- 3 files changed, 53 insertions(+), 24 deletions(-) rename src/lib/server/api/{ => infrastructure}/email-templates/email-verification.handlebars (100%) diff --git a/README.md b/README.md index 5ce6766..64d2040 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,67 @@ -# create-svelte +# Sveltekit - Starter BYOB (Bring your own Backend) -Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte). +A scalable, testable, extensible, boilerplate for Sveltekit. -## Creating a project +Sveltekit is awesome. File-based routing, SSG/SSR, and having the ability to have a backend attatched to your frontend saves incredible amounts of time and effort. -If you're seeing this, you've probably already done this step. Congrats! +But that backend sometimes isn't enough. There are some projects that require more powerful and feature rich backends. I'm talking Middleware, guards, pipes, interceptors, testing, event-emitters, task scheduling, route versioning, and so on. -```bash -# create a new project in the current directory -npm create svelte@latest +People tend to think that Sveltekit/NextJS are a backend with a frontend attached. **This notion is rediculous** and I'm unsure why its circulated so much. The backend for these frameworks are to facilitate the features in which their frontends promote and make them so powerful. -# create a new project in my-app -npm create svelte@latest my-app +So whats the answer? + +We want to maintain simplicity, elegancy, and a solid DX. Why not just use what appears to be silenly infered to do from the docs? Create a catch-all route and attatch a fully featured api onto the node-process sveltekit already runs on. + +`/api/[...slugs]` + +```ts +import app from '$lib/api'; +import type { RequestHandler } from '@sveltejs/kit'; + +export const GET: RequestHandler = ({ request }) => app.fetch(request); +export const PUT: RequestHandler = ({ request }) => app.fetch(request); +export const DELETE: RequestHandler = ({ request }) => app.fetch(request); +export const POST: RequestHandler = ({ request }) => app.fetch(request); ``` -## Developing +## Library Selection -Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: +My selection of libraries are just what I've found success, **stable** and high cohesion with. This repo should just serve as a guide as to whats possible; not what libary is the best. -```bash -npm run dev +#### Auth -# or start the server and open the app in a new browser tab -npm run dev -- --open -``` +- **[Lucia](https://lucia-auth.com)**: Hits the right level of abstraction for me. Hand me the tools to build a secure authentication system and let me implement it to suite my needs -## Building +#### Database -To create a production version of your app: +- [Drizzle](https://orm.drizzle.team/) - Drizzle advertises itself as an ORM but I think its deceptive. Its a query builder with a migration client. Everytime I've used an ORM, I find myself fighting it for sometimes the simplist of use cases. Drizzle just gives you type-safety while querying SQL in a native fashion. Learn SQL, not ORMs. -```bash -npm run build -``` +#### Backend + +- **[Hono](https://hono.dev/)**: Fast, lightweight, and built on web standards; meaning it can run anywhere you're Sveltekit app can. It's essentially a better, newer, and ironically more stable Express.JS. This provides us an extreemely good foundation to cleanly build ontop of without having to teardown first. It has a zod adapter for validating DTO's which can be shared with the frontend too. + +#### Frontend + +- **[Sveltekit](https://kit.svelte.dev/)**: After trying Vue, React, Next, and pretty much every frotnend framework in the JS ecosystem, its safe to say I vastly prefer Svelte and its priority of building on web standards. + +#### Dependency Injection + +- **[TSyringe](https://github.com/microsoft/tsyringe)**: Lightweight dependency injection for JS/TS. If you're familiar with TypeDI, this is essentially the same but actively maintained and used by Microsoft. + +## Architecture + +We have a few popular architectures for structuring backends +* Technical +* Clean/Onion +* Domain Driven Design(DDD)/Vertical Slice Architecture(VSA) + +I choose to start with organizing my backends by technical imeplementions and evolve into one of the others as the project evolves. You don't have to strictly stick to any specific architecture, but they do serve as good guidelines. Alternatively, move things around until it feels right. + + +## Testing + +Testing probably isn't first and foremost when creating an app. Thats fine. You shoulkdn't be spending time writing tests if your app is changing and pivoting. + +BUT a good stack should be **testable** when the time to solidify a codebase arrives. I created this stack with that pinciple in mind. I've provided a examples of how to write these tests under `authentication.service.test.ts` or `users.service.test.ts` -You can preview the production build with `npm run preview`. -> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment. diff --git a/src/lib/server/api/email-templates/email-verification.handlebars b/src/lib/server/api/infrastructure/email-templates/email-verification.handlebars similarity index 100% rename from src/lib/server/api/email-templates/email-verification.handlebars rename to src/lib/server/api/infrastructure/email-templates/email-verification.handlebars diff --git a/src/lib/server/api/services/mailer.service.ts b/src/lib/server/api/services/mailer.service.ts index bf2b3fa..2f54b0a 100644 --- a/src/lib/server/api/services/mailer.service.ts +++ b/src/lib/server/api/services/mailer.service.ts @@ -53,7 +53,7 @@ export class MailerService { const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file const __dirname = path.dirname(__filename); // get the name of the directory return fs.readFileSync( - path.join(__dirname, `../email-templates/${template}.handlebars`), + path.join(__dirname, `../infrastructure/email-templates/${template}.handlebars`), 'utf-8' ); }