feat: setup drizzle (#594)

* chore: migration to SvelteKit 2

* stage 1: migrate to svelte 5 and fix rerendering issues

* stage 2: fix more $: reactivity across dashboard

* fix merge conflicts

* chore: migrate code in main to svelte 5

* chore: update preventDefault

* chore: simplify tsconfig and remove unused mobileMenuRef in MobileMenu.svelte

* chore: enforce .ts across dashboard

* rename from classroomio-com to website

* stage-3: Replace carbon icon svelte with lucide icon

* update lock file

* chore: finish icon replacement

* fix: settings and setup page multiple rerender

* stage 3: More icon and rerendering fixes

* feat: setup drizzle and better auth

* fix: onboarding validation error showing translation key #586 (#593)

* fix: onboarding validation error showing translation key #586

* fix: remove debug log for profile update errors

* chore: add a clean command

* fix: remove message from email verification response
This commit is contained in:
Rotimi Best
2025-11-01 15:49:29 +01:00
committed by GitHub
parent 97fb446df5
commit b96d91cd7c
801 changed files with 22279 additions and 10834 deletions
+3 -3
View File
@@ -2,11 +2,11 @@ import 'dotenv/config';
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { courseRouter } from '$src/routes/course/course';
import { courseRouter } from '@api/routes/course/course';
import { logger } from 'hono/logger';
import { mailRouter } from '$src/routes/mail';
import { mailRouter } from '@api/routes/mail';
import { prettyJSON } from 'hono/pretty-json';
import { rateLimiterMiddleware } from '$src/middlewares/rate-limiter';
import { rateLimiterMiddleware } from '@api/middlewares/rate-limiter';
import { secureHeaders } from 'hono/secure-headers';
// Create Hono app with chaining for RPC support
+1 -1
View File
@@ -1,4 +1,4 @@
import { env } from '$src/config/env';
import { env } from '@api/config/env';
export * from './rate-limiter';
+3 -3
View File
@@ -1,8 +1,8 @@
import 'dotenv/config';
import { app } from '$src/app';
import { configureOpenAPI } from '$src/utils/openapi';
import { env } from '$src/config/env';
import { app } from '@api/app';
import { configureOpenAPI } from '@api/utils/openapi';
import { env } from '@api/config/env';
import { serve } from '@hono/node-server';
import { showRoutes } from 'hono/dev';
+1 -1
View File
@@ -1,6 +1,6 @@
import { Context, Next } from 'hono';
import { validateUser } from '$src/utils/auth/validate-user';
import { validateUser } from '@api/utils/auth/validate-user';
export const authMiddleware = async (c: Context, next: Next) => {
try {
+2 -2
View File
@@ -3,10 +3,10 @@ import {
ERROR_MESSAGES,
HTTP_STATUS,
RATE_LIMIT_HEADERS
} from '$src/constants/rate-limiter';
} from '@api/constants/rate-limiter';
import type { MiddlewareHandler } from 'hono';
import { rateLimiter } from '$src/utils/redis/limiter';
import { rateLimiter } from '@api/utils/redis/limiter';
import { userKeyGenerator } from '../utils/redis/key-generators';
export interface RateLimiterOptions {
+8 -8
View File
@@ -1,12 +1,12 @@
import { TCourseClone,TCourseDownloadContent, TCertificateDownload, ZCertificateDownload, ZCourseDownloadContent } from '$src/types/course';
import { Hono } from 'hono';
import { generateCertificate } from '$src/utils/certificate';
import { generateCoursePdf } from '$src/utils/course';
import { katexRouter } from '$src/routes/course/katex';
import { lessonRouter } from '$src/routes/course/lesson';
import { presignRouter } from '$src/routes/course/presign';
import { cloneRouter } from '$src/routes/course/clone';
import { TCourseClone,TCourseDownloadContent, TCertificateDownload, ZCertificateDownload, ZCourseDownloadContent } from '@api/types/course';
import { generateCertificate } from '@api/utils/certificate';
import { generateCoursePdf } from '@api/utils/course';
import { katexRouter } from '@api/routes/course/katex';
import { lessonRouter } from '@api/routes/course/lesson';
import { presignRouter } from '@api/routes/course/presign';
import { cloneRouter } from '@api/routes/course/clone';
import { zValidator } from '@hono/zod-validator';
export const courseRouter = new Hono()
+2 -2
View File
@@ -1,6 +1,6 @@
import { Hono } from 'hono';
import { TLessonDownloadContent, ZLessonDownloadContent } from '$src/types/course/lesson';
import { generateLessonPdf } from '$src/utils/lesson';
import { TLessonDownloadContent, ZLessonDownloadContent } from '@api/types/course/lesson';
import { generateLessonPdf } from '@api/utils/lesson';
import { zValidator } from '@hono/zod-validator';
export const lessonRouter = new Hono().post(
+7 -7
View File
@@ -3,17 +3,17 @@ import {
ZCourseDocumentPresignUrlUpload,
ZCourseDownloadPresignedUrl,
ZCoursePresignUrlUpload
} from '$src/types/course';
} from '@api/types/course';
import { describeRoute, validator } from 'hono-openapi';
import { BUCKET_NAME } from '$src/constants/upload';
import { CLOUDFLARE } from '$src/constants';
import type { GetSignedUrlParameters } from '$src/utils/s3';
import { BUCKET_NAME } from '@api/constants/upload';
import { CLOUDFLARE } from '@api/constants';
import type { GetSignedUrlParameters } from '@api/utils/s3';
import { Hono } from 'hono';
import { authMiddleware } from '$src/middlewares/auth';
import { generateFileKey } from '$src/utils/upload';
import { authMiddleware } from '@api/middlewares/auth';
import { generateFileKey } from '@api/utils/upload';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
import { s3Client } from '$src/utils/s3';
import { s3Client } from '@api/utils/s3';
// Response schemas for OpenAPI documentation
const PresignUploadResponse = {
+3 -3
View File
@@ -1,8 +1,8 @@
import { sendWithNodemailer, sendWithZoho } from '$src/services/mail';
import { sendWithNodemailer, sendWithZoho } from '@api/services/mail';
import { Hono } from 'hono';
import { ZSendEmailValidation } from '$src/types/mail';
import { env } from '$src/config/env';
import { ZSendEmailValidation } from '@api/types/mail';
import { env } from '@api/config/env';
import { zValidator } from '@hono/zod-validator';
export const mailRouter = new Hono().post(
+4 -4
View File
@@ -1,10 +1,10 @@
import { extractNameAndEmail, withEmailTemplate } from '$src/utils/mail';
import { nodemailerTransporter, zohoClient } from '$src/utils/email';
import { extractNameAndEmail, withEmailTemplate } from '@api/utils/mail';
import { nodemailerTransporter, zohoClient } from '@api/utils/email';
import { Hono } from 'hono';
import type { TSendEmailValidation } from '$src/types/mail';
import type { TSendEmailValidation } from '@api/types/mail';
import type { Transporter } from 'nodemailer';
import { env } from '$src/config/env';
import { env } from '@api/config/env';
export const mailRouter = new Hono();
+1 -1
View File
@@ -1,4 +1,4 @@
import { ALLOWED_CONTENT_TYPES, ALLOWED_DOCUMENT_TYPES } from '$src/constants/upload';
import { ALLOWED_CONTENT_TYPES, ALLOWED_DOCUMENT_TYPES } from '@api/constants/upload';
import { z } from 'zod';
+2 -2
View File
@@ -1,5 +1,5 @@
import type { TCertificateDownload } from '$src/types/course/lesson';
import { getCloudflarePdfBuffer } from '$src/utils/cloudflare';
import type { TCertificateDownload } from '@api/types/course/lesson';
import { getCloudflarePdfBuffer } from '@api/utils/cloudflare';
export interface CertificateData {
theme: string;
+1 -1
View File
@@ -1,4 +1,4 @@
import { CLOUDFLARE } from '$src/constants';
import { CLOUDFLARE } from '@api/constants';
export const getCloudflarePdfBuffer = async (html: string, styles?: string) => {
console.log('Generating PDF with Cloudflare API...');
+2 -2
View File
@@ -1,5 +1,5 @@
import type { TCourseDownloadContent } from '$src/types/course';
import { getCloudflarePdfBuffer } from '$src/utils/cloudflare';
import type { TCourseDownloadContent } from '@api/types/course';
import { getCloudflarePdfBuffer } from '@api/utils/cloudflare';
import { marked } from 'marked';
function getHtmlTemplate(body: string): string {
+1 -1
View File
@@ -1,6 +1,6 @@
import { SendMailClient } from 'zeptomail';
import type { Transporter } from 'nodemailer';
import { env } from '$src/config/env';
import { env } from '@api/config/env';
import nodemailer from 'nodemailer';
export const zohoClient = new SendMailClient({
+1 -1
View File
@@ -1,4 +1,4 @@
import type { TLessonDownloadContent } from '$src/types/course/lesson';
import type { TLessonDownloadContent } from '@api/types/course/lesson';
import { marked } from 'marked';
function getHtmlTemplate(body: string): string {
+1 -1
View File
@@ -1,6 +1,6 @@
import { Hono } from 'hono';
import { Scalar } from '@scalar/hono-api-reference';
import { env } from '$src/config/env';
import { env } from '@api/config/env';
export function configureOpenAPI(app: Hono) {
if (env.OPENAPI_URL) {
+1 -1
View File
@@ -4,7 +4,7 @@
*/
import type { Context } from 'hono';
import { supabase } from '$src/utils/supabase';
import { supabase } from '@api/utils/supabase';
/**
* Extract user ID from JWT token
+1 -1
View File
@@ -3,7 +3,7 @@ import {
DEFAULT_WINDOW_MS,
ERROR_MESSAGES,
RATE_LIMIT_KEY_PREFIX
} from '$src/constants/rate-limiter';
} from '@api/constants/rate-limiter';
import { Redis } from 'ioredis';
import { redis } from './redis';
+1 -1
View File
@@ -1,4 +1,4 @@
import { Redis } from 'ioredis';
import { env } from '$src/config/env';
import { env } from '@api/config/env';
export const redis = new Redis(env.REDIS_URL);
+1 -1
View File
@@ -8,7 +8,7 @@ import {
S3Client
} from '@aws-sdk/client-s3';
import { CLOUDFLARE } from '$src/constants';
import { CLOUDFLARE } from '@api/constants';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
export type GetSignedUrlParameters = Parameters<typeof getSignedUrl>;
+1 -1
View File
@@ -1,6 +1,6 @@
import { SupabaseClient, createClient } from '@supabase/supabase-js';
import { env } from '$src/config/env';
import { env } from '@api/config/env';
const { PUBLIC_SUPABASE_ANON_KEY, PUBLIC_SUPABASE_URL, PRIVATE_SUPABASE_SERVICE_ROLE } = env;