Elysia.js Samples

Elysia.js modern TypeScript web framework examples including Hello World, routing, validation, and plugin development

Key Facts

Category
Web Frameworks
Items
8
Format Families
text

Sample Overview

Elysia.js modern TypeScript web framework examples including Hello World, routing, validation, and plugin development This sample set belongs to Web Frameworks and can be used to test related workflows inside Elysia Tools.

💻 Elysia.js Hello World typescript

🟢 simple

Basic Elysia.js server setup and Hello World application with TypeScript

// Elysia.js Hello World Examples

import { Elysia } from 'elysia'

// 1. Basic Hello World server
const appBasic = new Elysia()
    .get('/', () => 'Hello, World!')
    .listen(3000)

console.log(`🦊 Elysia is running at ${appBasic.server?.hostname}:${appBasic.server?.port}`)

// 2. Hello World with different routes
const appRoutes = new Elysia()
    .get('/', () => 'Hello, Elysia!')
    .get('/hello', () => 'Hello from Elysia.js!')
    .get('/hello/:name', ({ params: { name } }) => `Hello, ${name}!`)
    .listen(3000)

// 3. JSON response
const appJson = new Elysia()
    .get('/api/hello', () => ({
        message: 'Hello, World!',
        timestamp: new Date().toISOString(),
        version: '1.0.0',
        framework: 'Elysia.js'
    }))
    .listen(3000)

// 4. HTML response
const appHtml = new Elysia()
    .get('/html', () => (
        <html>
            <head>
                <title>Hello Elysia</title>
            </head>
            <body>
                <h1>Hello, World!</h1>
                <p>This is an HTML response from Elysia.js</p>
            </body>
        </html>
    ))
    .listen(3000)

// 5. Typed responses
const appTyped = new Elysia()
    .get('/typed', () => ({
        id: 1,
        name: 'Elysia.js',
        features: ['TypeScript', 'Performance', 'Simple API'] as const
    }))
    .listen(3000)

// 6. Async handlers
const appAsync = new Elysia()
    .get('/async', async () => {
        await new Promise(resolve => setTimeout(resolve, 1000))
        return 'Async response from Elysia!'
    })
    .listen(3000)

// 7. Error handling
const appError = new Elysia()
    .get('/error', () => {
        throw new Error('Something went wrong!')
    })
    .onError(({ code, error }) => {
        if (code === 'NOT_FOUND')
            return 'Route not found :('

        return new Response(error.toString(), {
            status: 500
        })
    })
    .listen(3000)

// 8. Chain configuration
const appConfig = new Elysia()
    .state('version', '1.0.0')
    .decorate('getDate', () => new Date())
    .get('/', ({ getDate, store: { version } }) => ({
        date: getDate(),
        version
    }))
    .listen(3000)

💻 Elysia.js Routing and Parameters typescript

🟡 intermediate

Advanced routing examples with path parameters, query strings, and HTTP methods

// Elysia.js Routing Examples

import { Elysia } from 'elysia'

// 1. HTTP Methods
const app = new Elysia()
    .get('/users', () => 'Get all users')
    .post('/users', () => 'Create a new user')
    .put('/users/:id', ({ params: { id } }) => `Update user ${id}`)
    .patch('/users/:id', ({ params: { id } }) => `Patch user ${id}`)
    .delete('/users/:id', ({ params: { id } }) => `Delete user ${id}`)
    .listen(3000)

// 2. Path parameters
interface UserParams {
    id: string
}

const app = new Elysia()
    .get('/users/:id', ({ params: { id } }: { params: UserParams }) => {
        return `User ID: ${id}`
    })
    .get('/posts/:category/:slug', ({ params }) => {
        return `Category: ${params.category}, Slug: ${params.slug}`
    })
    .listen(3000)

// 3. Query parameters
const app = new Elysia()
    .get('/search', ({ query }) => {
        const { q, limit = '10', page = '1' } = query
        return {
            query: q || 'No query provided',
            limit: parseInt(limit),
            page: parseInt(page),
            results: [`Result for "${q}"`]
        }
    })
    .listen(3000)

// 4. Headers
const app = new Elysia()
    .get('/info', ({ headers }) => {
        return {
            userAgent: headers['user-agent'],
            accept: headers.accept,
            host: headers.host
        }
    })
    .listen(3000)

// 5. Request body
interface CreateUserBody {
    name: string
    email: string
    age?: number
}

const app = new Elysia()
    .post('/users', ({ body }: { body: CreateUserBody }) => {
        return {
            message: `User ${body.name} created successfully!`,
            user: {
                id: Math.random(),
                name: body.name,
                email: body.email,
                age: body.age || 0
            }
        }
    })
    .listen(3000)

// 6. Route groups
const app = new Elysia()
    .group('/api/v1', (app) => app
        .get('/users', () => ['user1', 'user2'])
        .post('/users', () => 'User created')
        .get('/posts', () => ['post1', 'post2'])
    )
    .group('/api/v2', (app) => app
        .get('/users', () => ['user1', 'user2', 'user3'])
        .get('/posts', () => ['post1', 'post2', 'post3'])
    )
    .listen(3000)

// 7. Wildcard routes
const app = new Elysia()
    .get('/static/*', ({ params }) => {
        return `Serving file: ${params['*']}`
    })
    .all('/fallback/*', () => {
        return 'This is a catch-all route'
    })
    .listen(3000)

// 8. Route guards
const app = new Elysia()
    .guard({
        beforeHandle({ set, headers }) {
            const auth = headers.authorization
            if (!auth?.startsWith('Bearer ')) {
                set.status = 401
                return 'Unauthorized'
            }
        }
    }, (app) => app
        .get('/protected', () => 'Protected data')
        .post('/protected', () => 'Protected action')
    )
    .get('/public', () => 'Public data')
    .listen(3000)

// 9. Custom responses
const app = new Elysia()
    .get('/custom-status', ({ set }) => {
        set.status = 418
        return "I'm a teapot"
    })
    .get('/redirect', ({ set }) => {
        set.headers['Location'] = '/'
        set.status = 302
        return
    })
    .listen(3000)

// 10. Route patterns
const app = new Elysia()
    .match('GET|POST', '/users', ({ request }) => {
        return `${request.method} /users`
    })
    .match(['PUT', 'PATCH'], '/users/:id', ({ request, params }) => {
        return `${request.method} /users/${params.id}`
    })
    .listen(3000)

💻 Elysia.js Data Validation typescript

🟡 intermediate

TypeScript-first validation using built-in schema validation

// Elysia.js Validation Examples

import { Elysia, t } from 'elysia'

// 1. Basic body validation
const app = new Elysia()
    .post('/users', ({ body }) => {
        return `User ${body.name} (${body.email}) created!`
    }, {
        body: t.Object({
            name: t.String(),
            email: t.String({ format: 'email' }),
            age: t.Number({ minimum: 18 })
        })
    })
    .listen(3000)

// 2. Query parameter validation
const app = new Elysia()
    .get('/search', ({ query }) => {
        return `Searching for "${query.q}" with limit ${query.limit}`
    }, {
        query: t.Object({
            q: t.String({ minLength: 1 }),
            limit: t.Optional(t.Number({ minimum: 1, maximum: 100 })),
            category: t.Optional(t.Enum(['tech', 'news', 'sports'] as const))
        })
    })
    .listen(3000)

// 3. Path parameter validation
const app = new Elysia()
    .get('/users/:id', ({ params: { id } }) => {
        return `User ID: ${id}`
    }, {
        params: t.Object({
            id: t.Numeric()
        })
    })
    .listen(3000)

// 4. Header validation
const app = new Elysia()
    .post('/data', ({ headers }) => {
        return 'Data received'
    }, {
        headers: t.Object({
            'content-type': t.Literal('application/json'),
            'x-api-key': t.String({ minLength: 10 })
        })
    })
    .listen(3000)

// 5. Response validation
const app = new Elysia()
    .get('/user/:id', ({ params: { id } }) => {
        return {
            id: parseInt(id),
            name: `User ${id}`,
            email: `user${id}@example.com`,
            createdAt: new Date()
        }
    }, {
        params: t.Object({
            id: t.Numeric()
        }),
        response: {
            200: t.Object({
                id: t.Number(),
                name: t.String(),
                email: t.String({ format: 'email' }),
                createdAt: t.Date()
            }),
            404: t.Object({
                error: t.String()
            })
        }
    })
    .listen(3000)

// 6. Custom validation with transform
const app = new Elysia()
    .post('/register', ({ body }) => {
        return body
    }, {
        body: t.Object({
            username: t.String({
                minLength: 3,
                maxLength: 20,
                pattern: '^[a-zA-Z0-9_]+$'
            }),
            email: t.String({ format: 'email' }),
            password: t.String({ minLength: 8 }),
            confirmPassword: t.String()
        }),
        transform({ body }) {
            body.username = body.username.toLowerCase()
        }
    })
    .listen(3000)

// 7. Array validation
const app = new Elysia()
    .post('/batch', ({ body }) => {
        return `Processed ${body.items.length} items`
    }, {
        body: t.Object({
            items: t.Array(t.Object({
                id: t.Number(),
                name: t.String(),
                price: t.Number({ minimum: 0 })
            })),
            metadata: t.Optional(t.Object({
                total: t.Number(),
                currency: t.String({ default: 'USD' })
            }))
        })
    })
    .listen(3000)

// 8. Nested object validation
const app = new Elysia()
    .post('/order', ({ body }) => {
        return 'Order created'
    }, {
        body: t.Object({
            customer: t.Object({
                name: t.String(),
                address: t.Object({
                    street: t.String(),
                    city: t.String(),
                    zipCode: t.String(),
                    country: t.String()
                })
            }),
            items: t.Array(t.Object({
                productId: t.Number(),
                quantity: t.Number({ minimum: 1 }),
                price: t.Number()
            })),
            shipping: t.Optional(t.Union([
                t.Literal('standard'),
                t.Literal('express'),
                t.Literal('overnight')
            ]))
        })
    })
    .listen(3000)

// 9. File upload validation
const app = new Elysia()
    .post('/upload', ({ body: { file } }) => {
        return `Uploaded file: ${file.name} (${file.size} bytes)`
    }, {
        body: t.Object({
            file: t.File({
                type: ['image/jpeg', 'image/png', 'image/gif'],
                maxSize: '5m'
            }),
            description: t.Optional(t.String({ maxLength: 500 }))
        })
    })
    .listen(3000)

// 10. Custom error messages
const app = new Elysia()
    .onError(({ code, error }) => {
        if (code === 'VALIDATION') {
            return {
                success: false,
                errors: error.all.map(({ path, message }) => ({
                    field: path.join('.'),
                    message
                }))
            }
        }
    })
    .post('/custom-validation', ({ body }) => {
        return 'Success'
    }, {
        body: t.Object({
            username: t.String({
                error: 'Username must be a string'
            }),
            email: t.String({
                format: 'email',
                error: 'Invalid email format'
            })
        })
    })
    .listen(3000)

💻 Elysia.js Middleware and Hooks typescript

🟡 intermediate

Lifecycle hooks, middleware, and advanced request handling

// Elysia.js Middleware and Hooks Examples

import { Elysia } from 'elysia'

// 1. Before handle hook
const app = new Elysia()
    .onBeforeHandle({ as: 'global' }, ({ set, headers }) => {
        // Add CORS headers
        set.headers['Access-Control-Allow-Origin'] = '*'
        set.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
        set.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
    })
    .get('/data', () => 'CORS enabled data')
    .listen(3000)

// 2. After handle hook
const app = new Elysia()
    .onAfterHandle({ as: 'global' }, ({ response }) => {
        // Wrap all responses
        return {
            success: true,
            timestamp: new Date().toISOString(),
            data: response
        }
    })
    .get('/users', () => ['Alice', 'Bob', 'Charlie'])
    .listen(3000)

// 3. Transform hook
const app = new Elysia()
    .onTransform({ as: 'global' }, ({ request }) => {
        console.log(`${request.method} ${request.url}`)
    })
    .get('/track', () => 'Tracked request')
    .listen(3000)

// 4. Logger middleware
const logger = new Elysia({ name: 'logger' })
    .onBeforeHandle(({ request, set }) => {
        console.log(`[${new Date().toISOString()}] ${request.method} ${request.url}`)
    })
    .onAfterHandle(({ response }) => {
        console.log(`Response: ${JSON.stringify(response)}`)
    })

const app = new Elysia()
    .use(logger)
    .get('/logged', () => 'This request is logged')
    .listen(3000)

// 5. Authentication middleware
const auth = new Elysia({ name: 'auth' })
    .derive({ as: 'global' }, ({ headers }) => {
        const authHeader = headers.authorization
        if (!authHeader?.startsWith('Bearer ')) {
            throw new Error('Unauthorized')
        }

        const token = authHeader.slice(7)
        // Simplified token validation
        const user = { id: 1, name: 'John Doe' }
        return { user }
    })

const app = new Elysia()
    .use(auth)
    .get('/profile', ({ user }) => `Hello, ${user.name}!`)
    .listen(3000)

// 6. Rate limiting middleware
const rateLimiter = new Map<string, { count: number; resetTime: number }>()

const rateLimit = new Elysia({ name: 'rate-limit' })
    .onBeforeHandle(({ set, headers }) => {
        const ip = headers['x-forwarded-for'] || 'unknown'
        const now = Date.now()
        const windowMs = 60 * 1000 // 1 minute
        const maxRequests = 10

        const record = rateLimiter.get(ip)

        if (!record || now > record.resetTime) {
            rateLimiter.set(ip, { count: 1, resetTime: now + windowMs })
            return
        }

        if (record.count >= maxRequests) {
            set.status = 429
            return 'Too many requests'
        }

        record.count++
    })

const app = new Elysia()
    .use(rateLimit)
    .get('/limited', () => 'Rate limited endpoint')
    .listen(3000)

// 7. Error handling
const app = new Elysia()
    .onError(({ code, error, set }) => {
        switch (code) {
            case 'NOT_FOUND':
                set.status = 404
                return { error: 'Route not found' }

            case 'VALIDATION':
                set.status = 400
                return {
                    error: 'Validation failed',
                    details: error.all
                }

            case 'INTERNAL_SERVER_ERROR':
                set.status = 500
                return { error: 'Internal server error' }

            default:
                set.status = 500
                return { error: 'Unknown error' }
        }
    })
    .get('/error', () => {
        throw new Error('Test error')
    })
    .listen(3000)

// 8. Request context extension
const app = new Elysia()
    .state('version', '1.0.0')
    .decorate('getDb', () => {
        // Mock database connection
        return {
            query: (sql: string) => `Executing: ${sql}`,
            close: () => console.log('DB connection closed')
        }
    })
    .derive({ as: 'global' }, ({ store }) => {
        return {
            appInfo: {
                version: store.version,
                uptime: process.uptime()
            }
        }
    })
    .get('/context', ({ getDb, appInfo }) => {
        return {
            db: getDb().query('SELECT * FROM users'),
            appInfo
        }
    })
    .listen(3000)

// 9. Plugin system
const loggingPlugin = new Elysia({ name: 'logging' })
    .onBeforeHandle(({ request }) => {
        console.log(`📝 ${request.method} ${request.url}`)
    })
    .onAfterHandle(() => {
        console.log('✅ Request completed')
    })
    .onError(({ error }) => {
        console.log(`❌ Error: ${error.message}`)
    })

const timingPlugin = new Elysia({ name: 'timing' })
    .onBeforeHandle(() => ({ startTime: Date.now() }))
    .onAfterHandle({ beforeHandle: ({ startTime }) => ({ startTime }) }, ({ startTime }) => {
        const duration = Date.now() - startTime
        console.log(`⏱️ Request took ${duration}ms`)
    })

const app = new Elysia()
    .use(loggingPlugin)
    .use(timingPlugin)
    .get('/plugged', () => 'This request uses multiple plugins')
    .listen(3000)

// 10. Route-specific hooks
const app = new Elysia()
    .get('/specific',
        () => 'Route with specific hooks',
        {
            beforeHandle({ set }) {
                set.headers['X-Custom'] = 'value'
            },
            afterHandle({ response }) {
                return `Processed: ${response}`
            }
        }
    )
    .listen(3000)

// 11. Lifecycle order demonstration
const app = new Elysia()
    .onRequest(() => console.log('1. onRequest'))
    .onBeforeHandle(() => console.log('2. onBeforeHandle'))
    .onAfterHandle(() => console.log('3. onAfterHandle'))
    .onResponse(() => console.log('4. onResponse'))
    .get('/lifecycle', () => {
        console.log('-> Handler executing')
        return 'Lifecycle demo'
    })
    .listen(3000)

💻 Elysia.js WebSocket Support typescript

🟡 intermediate

Real-time WebSocket communication and chat examples

// Elysia.js WebSocket Examples

import { Elysia } from 'elysia'
import { websocket } from '@elysiajs/websocket'

// 1. Basic WebSocket server
const app = new Elysia()
    .use(websocket())
    .ws('/ws', {
        message(ws, message) {
            ws.send(`Echo: ${message}`)
        },
        open(ws) {
            console.log('WebSocket connection opened')
            ws.send('Welcome to the WebSocket server!')
        },
        close(ws) {
            console.log('WebSocket connection closed')
        }
    })
    .listen(3000)

// 2. Chat server
interface ChatMessage {
    type: 'message' | 'join' | 'leave'
    user: string
    content: string
    timestamp: string
}

const clients = new Map<string, any>()

const app = new Elysia()
    .use(websocket())
    .ws('/chat', {
        message(ws, message: ChatMessage) {
            const chatMessage: ChatMessage = {
                type: 'message',
                user: message.user,
                content: message.content,
                timestamp: new Date().toISOString()
            }

            // Broadcast to all connected clients
            app.server?.publish('chat', JSON.stringify(chatMessage))
        },
        open(ws) {
            const userId = `user_${Math.random().toString(36).substr(2, 9)}`
            ws.data.id = userId
            clients.set(userId, ws)

            const joinMessage: ChatMessage = {
                type: 'join',
                user: 'System',
                content: `User ${userId} joined the chat`,
                timestamp: new Date().toISOString()
            }

            app.server?.publish('chat', JSON.stringify(joinMessage))
        },
        close(ws) {
            const userId = ws.data.id
            clients.delete(userId)

            const leaveMessage: ChatMessage = {
                type: 'leave',
                user: 'System',
                content: `User ${userId} left the chat`,
                timestamp: new Date().toISOString()
            }

            app.server?.publish('chat', JSON.stringify(leaveMessage))
        }
    })
    .listen(3000)

// 3. Real-time notifications
const app = new Elysia()
    .use(websocket())
    .ws('/notifications', {
        open(ws) {
            console.log('Notification client connected')

            // Send periodic notifications
            const interval = setInterval(() => {
                const notification = {
                    type: 'notification',
                    title: 'System Update',
                    message: `System time: ${new Date().toLocaleTimeString()}`,
                    timestamp: new Date().toISOString()
                }

                ws.send(JSON.stringify(notification))
            }, 5000)

            ws.data.interval = interval
        },
        close(ws) {
            if (ws.data.interval) {
                clearInterval(ws.data.interval)
            }
        }
    })
    .listen(3000)

// 4. Multi-room chat
interface Room {
    id: string
    name: string
    clients: Map<string, any>
}

const rooms = new Map<string, Room>()

const app = new Elysia()
    .use(websocket())
    .ws('/room/:roomId', {
        params: {
            roomId: t.String()
        },
        message(ws, message) {
            const { roomId } = ws.data.params
            const room = rooms.get(roomId)

            if (!room) return

            const chatMessage = {
                type: 'message',
                user: ws.data.user,
                content: message.content,
                timestamp: new Date().toISOString()
            }

            // Send to all clients in the room
            room.clients.forEach((client) => {
                client.send(JSON.stringify(chatMessage))
            })
        },
        open(ws) {
            const { roomId } = ws.data.params
            const userId = `user_${Math.random().toString(36).substr(2, 9)}`

            ws.data.user = userId
            ws.data.roomId = roomId

            // Get or create room
            let room = rooms.get(roomId)
            if (!room) {
                room = {
                    id: roomId,
                    name: `Room ${roomId}`,
                    clients: new Map()
                }
                rooms.set(roomId, room)
            }

            // Add client to room
            room.clients.set(userId, ws)

            const joinMessage = {
                type: 'join',
                user: 'System',
                content: `${userId} joined the room`,
                timestamp: new Date().toISOString()
            }

            room.clients.forEach((client) => {
                client.send(JSON.stringify(joinMessage))
            })
        },
        close(ws) {
            const { roomId, user } = ws.data
            const room = rooms.get(roomId)

            if (room) {
                room.clients.delete(user)

                const leaveMessage = {
                    type: 'leave',
                    user: 'System',
                    content: `${user} left the room`,
                    timestamp: new Date().toISOString()
                }

                room.clients.forEach((client) => {
                    client.send(JSON.stringify(leaveMessage))
                })

                // Clean up empty rooms
                if (room.clients.size === 0) {
                    rooms.delete(roomId)
                }
            }
        }
    })
    .listen(3000)

// 5. WebSocket with HTTP API
interface Todo {
    id: number
    text: string
    completed: boolean
    createdAt: string
}

const todos: Todo[] = [
    { id: 1, text: 'Learn Elysia.js', completed: true, createdAt: new Date().toISOString() },
    { id: 2, text: 'Build WebSocket app', completed: false, createdAt: new Date().toISOString() }
]

const app = new Elysia()
    .use(websocket())
    .ws('/todos', {
        open(ws) {
            // Send initial todos
            ws.send(JSON.stringify({
                type: 'todos',
                data: todos
            }))
        }
    })
    .get('/api/todos', () => todos)
    .post('/api/todos', ({ body }) => {
        const newTodo: Todo = {
            id: Date.now(),
            text: body.text,
            completed: false,
            createdAt: new Date().toISOString()
        }

        todos.push(newTodo)

        // Broadcast to all WebSocket clients
        app.server?.publish('todos', JSON.stringify({
            type: 'todo-added',
            data: newTodo
        }))

        return newTodo
    })
    .put('/api/todos/:id', ({ params, body }) => {
        const todo = todos.find(t => t.id === parseInt(params.id))
        if (!todo) return null

        Object.assign(todo, body)

        // Broadcast update
        app.server?.publish('todos', JSON.stringify({
            type: 'todo-updated',
            data: todo
        }))

        return todo
    })
    .delete('/api/todos/:id', ({ params }) => {
        const index = todos.findIndex(t => t.id === parseInt(params.id))
        if (index === -1) return null

        const deletedTodo = todos.splice(index, 1)[0]

        // Broadcast deletion
        app.server?.publish('todos', JSON.stringify({
            type: 'todo-deleted',
            data: { id: deletedTodo.id }
        }))

        return deletedTodo
    })
    .listen(3000)

// 6. WebSocket authentication
const app = new Elysia()
    .use(websocket())
    .ws('/auth', {
        beforeHandle({ headers, set }) {
            const token = headers.authorization?.replace('Bearer ', '')

            // Simple token validation
            if (!token || token !== 'valid-token') {
                set.headers['sec-websocket-protocol'] = 'close'
                return 'Unauthorized'
            }
        },
        message(ws, message) {
            ws.send(`Authenticated message: ${message}`)
        },
        open(ws) {
            ws.send('WebSocket connection authenticated')
        }
    })
    .listen(3000)

// 7. WebSocket with binary data
const app = new Elysia()
    .use(websocket())
    .ws('/binary', {
        message(ws, message) {
            if (message instanceof ArrayBuffer) {
                // Echo binary data
                ws.send(message)
            } else {
                ws.send(`Received text: ${message}`)
            }
        },
        open(ws) {
            ws.send('Binary WebSocket server ready')
        }
    })
    .listen(3000)

💻 Elysia.js Authentication typescript

🟡 intermediate

JWT authentication, OAuth, and authorization patterns

// Elysia.js Authentication Examples

import { Elysia, t } from 'elysia'
import { jwt } from '@elysiajs/jwt'

// 1. JWT Authentication
const app = new Elysia()
    .use(
        jwt({
            name: 'jwt',
            secret: process.env.JWT_SECRET || 'your-secret-key-here'
        })
    )
    .post('/login', async ({ body, jwt }) => {
        // Validate user credentials (in real app, check database)
        const { username, password } = body

        // Mock user validation
        if (username === 'admin' && password === 'password123') {
            const payload = {
                sub: '1234567890',
                name: 'John Doe',
                email: '[email protected]',
                role: 'admin',
                iat: Math.floor(Date.now() / 1000)
            }

            const token = await jwt.sign(payload)
            return {
                success: true,
                token,
                user: {
                    id: payload.sub,
                    name: payload.name,
                    email: payload.email,
                    role: payload.role
                }
            }
        }

        return {
            success: false,
            message: 'Invalid credentials'
        }
    }, {
        body: t.Object({
            username: t.String(),
            password: t.String({ minLength: 6 })
        })
    })
    .get('/protected', async ({ jwt, headers }) => {
        const auth = headers.authorization
        if (!auth?.startsWith('Bearer ')) {
            return { error: 'No token provided' }
        }

        const token = auth.slice(7)
        const payload = await jwt.verify(token)

        if (!payload) {
            return { error: 'Invalid token' }
        }

        return {
            message: 'Access granted',
            user: payload
        }
    })
    .listen(3000)

// 2. Middleware-based Authentication
const authMiddleware = new Elysia({ name: 'auth' })
    .use(
        jwt({
            name: 'jwt',
            secret: 'middleware-secret'
        })
    )
    .derive({ as: 'global' }, async ({ jwt, headers }) => {
        const auth = headers.authorization
        const token = auth?.replace('Bearer ', '')

        let user = null
        if (token) {
            user = await jwt.verify(token)
        }

        return {
            user,
            isAuthenticated: !!user
        }
    })
    .guard({
        beforeHandle({ user, set }) {
            if (!user) {
                set.status = 401
                return { error: 'Unauthorized' }
            }
        }
    }, (app) => app
        .get('/api/users', () => ['Alice', 'Bob', 'Charlie'])
        .post('/api/users', () => 'User created')
        .put('/api/users/:id', () => 'User updated')
    )
    .get('/public', () => 'Public endpoint')

const mainApp = new Elysia()
    .use(authMiddleware)
    .listen(3000)

// 3. Role-based Authorization
interface User {
    id: string
    name: string
    email: string
    role: 'admin' | 'user' | 'moderator'
    permissions: string[]
}

const rbacPlugin = new Elysia({ name: 'rbac' })
    .use(
        jwt({
            name: 'jwt',
            secret: 'rbac-secret'
        })
    )
    .derive({ as: 'global' }, async ({ jwt, headers }) => {
        const token = headers.authorization?.replace('Bearer ', '')

        if (!token) {
            return {
                user: null as User | null,
                hasRole: (role: string) => false,
                hasPermission: (permission: string) => false
            }
        }

        const payload = await jwt.verify(token) as any
        const user: User = payload?.user || null

        const hasRole = (role: string): boolean => {
            return user?.role === role
        }

        const hasPermission = (permission: string): boolean => {
            return user?.permissions?.includes(permission) || false
        }

        return { user, hasRole, hasPermission }
    })
    .guard({
        beforeHandle({ user, set }) {
            if (!user) {
                set.status = 401
                return { error: 'Unauthorized' }
            }
        }
    }, (app) => app
        .guard({
            beforeHandle({ hasRole, set }) {
                if (!hasRole('admin')) {
                    set.status = 403
                    return { error: 'Admin access required' }
                }
            }
        }, (app) => app
            .delete('/admin/users/:id', () => 'User deleted')
            .get('/admin/stats', () => 'Admin statistics')
        )
        .guard({
            beforeHandle({ hasPermission, set }) {
                if (!hasPermission('read:posts')) {
                    set.status = 403
                    return { error: 'Read permission required' }
                }
            }
        }, (app) => app
            .get('/posts', () => 'List of posts')
        )
        .post('/posts', () => 'Post created') // No specific permission required
    )

const app = new Elysia()
    .use(rbacPlugin)
    .listen(3000)

// 4. OAuth Integration (GitHub example)
const app = new Elysia()
    .state('oauth', {
        clientId: process.env.GITHUB_CLIENT_ID,
        clientSecret: process.env.GITHUB_CLIENT_SECRET,
        redirectUri: 'http://localhost:3000/auth/github/callback'
    })
    .get('/auth/github', ({ store: { oauth } }) => {
        const authUrl = `https://github.com/login/oauth/authorize?` +
            `client_id=${oauth.clientId}&` +
            `redirect_uri=${encodeURIComponent(oauth.redirectUri)}&` +
            `scope=user:email`

        return { authUrl }
    })
    .get('/auth/github/callback', async ({ query, store: { oauth }, jwt }) => {
        const { code } = query

        if (!code) {
            return { error: 'Authorization code not provided' }
        }

        // Exchange code for access token
        const tokenResponse = await fetch('https://github.com/login/oauth/access_token', {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                client_id: oauth.clientId,
                client_secret: oauth.clientSecret,
                code
            })
        }).then(res => res.json())

        if (tokenResponse.error) {
            return { error: tokenResponse.error_description }
        }

        // Get user information
        const userResponse = await fetch('https://api.github.com/user', {
            headers: {
                'Authorization': `token ${tokenResponse.access_token}`
            }
        }).then(res => res.json())

        // Create JWT token
        const payload = {
            sub: userResponse.id,
            name: userResponse.name,
            email: userResponse.email,
            avatar: userResponse.avatar_url,
            provider: 'github'
        }

        const token = await jwt.sign(payload)

        return {
            token,
            user: payload
        }
    })
    .listen(3000)

// 5. API Key Authentication
const apiKeys = new Set(['key1', 'key2', 'key3'])

const apiKeyAuth = new Elysia({ name: 'api-key' })
    .onBeforeHandle({ as: 'global' }, ({ headers, set }) => {
        const apiKey = headers['x-api-key']

        if (!apiKey || !apiKeys.has(apiKey)) {
            set.status = 401
            return { error: 'Invalid API key' }
        }

        // You could also load rate limits based on the API key
        set.headers['X-API-Key-Valid'] = 'true'
    })

const app = new Elysia()
    .use(apiKeyAuth)
    .get('/api/data', () => ({ data: 'Protected by API key' }))
    .post('/api/process', () => ({ result: 'Processing complete' }))
    .listen(3000)

// 6. Session-based Authentication
const sessions = new Map<string, any>()

const sessionAuth = new Elysia({ name: 'session' })
    .derive({ as: 'global' }, ({ headers, cookie }) => {
        const sessionId = cookie?.sessionId || headers['x-session-id']

        const session = sessionId ? sessions.get(sessionId) : null

        const createSession = (userData: any): string => {
            const newSessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
            sessions.set(newSessionId, {
                user: userData,
                createdAt: new Date(),
                lastAccessed: new Date()
            })
            return newSessionId
        }

        const destroySession = (sessionId: string): void => {
            sessions.delete(sessionId)
        }

        return { session, createSession, destroySession }
    })
    .guard({
        beforeHandle({ session, set }) {
            if (!session) {
                set.status = 401
                return { error: 'No valid session' }
            }
        }
    }, (app) => app
        .get('/dashboard', ({ session }) => ({
            user: session.user,
            message: 'Welcome to your dashboard'
        }))
        .post('/logout', ({ headers, cookie, destroySession }) => {
            const sessionId = cookie?.sessionId || headers['x-session-id']
            if (sessionId) {
                destroySession(sessionId)
            }
            return { message: 'Logged out successfully' }
        })
    )
    .post('/login', ({ body, createSession, cookie }) => {
        // Validate credentials
        if (body.username === 'user' && body.password === 'pass') {
            const sessionId = createSession({
                id: 1,
                name: 'John Doe',
                username: body.username
            })

            // Set session cookie
            cookie.sessionId.value = sessionId
            cookie.sessionId.httpOnly = true
            cookie.sessionId.maxAge = 3600

            return {
                success: true,
                sessionId,
                user: { id: 1, name: 'John Doe' }
            }
        }

        return { success: false, message: 'Invalid credentials' }
    })

const app = new Elysia()
    .use(sessionAuth)
    .listen(3000)

// 7. Refresh Token Pattern
const refreshTokens = new Map<string, any>()

const app = new Elysia()
    .use(
        jwt({
            name: 'accessJwt',
            secret: 'access-secret',
            exp: '1h' // Short-lived access token
        })
    )
    .use(
        jwt({
            name: 'refreshJwt',
            secret: 'refresh-secret',
            exp: '7d' // Long-lived refresh token
        })
    )
    .post('/auth/login', async ({ body, accessJwt, refreshJwt }) => {
        // Validate credentials
        if (body.username === 'admin' && body.password === 'password') {
            const user = {
                id: '1',
                name: 'Admin User',
                role: 'admin'
            }

            const accessToken = await accessJwt.sign({ user })
            const refreshToken = await refreshJwt.sign({ userId: user.id })

            // Store refresh token
            refreshTokens.set(refreshToken, {
                userId: user.id,
                createdAt: new Date()
            })

            return {
                accessToken,
                refreshToken,
                user
            }
        }

        throw new Error('Invalid credentials')
    })
    .post('/auth/refresh', async ({ body, accessJwt, refreshJwt }) => {
        const { refreshToken } = body

        // Validate refresh token
        const payload = await refreshJwt.verify(refreshToken)
        if (!payload || !refreshTokens.has(refreshToken)) {
            throw new Error('Invalid refresh token')
        }

        // Generate new access token
        const user = {
            id: payload.userId,
            name: 'User ' + payload.userId,
            role: 'user'
        }

        const accessToken = await accessJwt.sign({ user })

        return { accessToken }
    })
    .post('/auth/logout', ({ body }) => {
        const { refreshToken } = body
        refreshTokens.delete(refreshToken)
        return { message: 'Logged out successfully' }
    })
    .listen(3000)

// 8. Multi-factor Authentication (MFA)
const app = new Elysia()
    .state('mfa', {
        // In real app, use TOTP library
        generateMFACode: (userId: string) => {
            return Math.floor(100000 + Math.random() * 900000).toString()
        },
        verifyMFACode: (userId: string, code: string): boolean => {
            // Mock verification
            return code === '123456'
        }
    })
    .post('/auth/login-mfa', ({ body, store: { mfa } }) => {
        const { username, password } = body

        // Step 1: Validate username/password
        if (username === 'admin' && password === 'password') {
            const mfaCode = mfa.generateMFACode(username)
            // In real app, send MFA code via SMS/email
            console.log(`MFA Code for ${username}: ${mfaCode}`)

            return {
                requiresMFA: true,
                message: 'MFA code sent to your registered device'
            }
        }

        return { error: 'Invalid credentials' }
    })
    .post('/auth/verify-mfa', ({ body, store: { mfa }, jwt }) => {
        const { username, mfaCode } = body

        if (!mfa.verifyMFACode(username, mfaCode)) {
            return { error: 'Invalid MFA code' }
        }

        // Generate final authentication token
        return jwt.sign({
            sub: username,
            mfaVerified: true
        })
    })
    .listen(3000)

💻 Elysia.js GraphQL Integration typescript

🟡 intermediate

GraphQL server implementation with Elysia.js

// Elysia.js GraphQL Examples

import { Elysia } from 'elysia'
import { gql } from '@elysiajs/graphql'
import { graphql } from '@elysiajs/graphql'

// 1. Basic GraphQL Server
const typeDefs = gql`
    type Query {
        hello: String
        user(id: ID!): User
        users: [User!]
    }

    type User {
        id: ID!
        name: String!
        email: String!
        createdAt: String!
    }

    type Mutation {
        createUser(name: String!, email: String!): User
        updateUser(id: ID!, name: String): User
        deleteUser(id: ID!): Boolean
    }
`

// Mock data
const users = [
    { id: '1', name: 'John Doe', email: '[email protected]', createdAt: '2024-01-01' },
    { id: '2', name: 'Jane Smith', email: '[email protected]', createdAt: '2024-01-02' }
]

const resolvers = {
    Query: {
        hello: () => 'Hello, GraphQL with Elysia!',
        user: (_: any, { id }: { id: string }) => users.find(u => u.id === id),
        users: () => users
    },
    Mutation: {
        createUser: (_: any, { name, email }: { name: string; email: string }) => {
            const newUser = {
                id: (users.length + 1).toString(),
                name,
                email,
                createdAt: new Date().toISOString()
            }
            users.push(newUser)
            return newUser
        },
        updateUser: (_: any, { id, name }: { id: string; name?: string }) => {
            const user = users.find(u => u.id === id)
            if (!user) return null
            if (name) user.name = name
            return user
        },
        deleteUser: (_: any, { id }: { id: string }) => {
            const index = users.findIndex(u => u.id === id)
            if (index === -1) return false
            users.splice(index, 1)
            return true
        }
    }
}

const app = new Elysia()
    .use(
        graphql({
            typeDefs,
            resolvers
        })
    )
    .listen(3000)

// 2. GraphQL with Context and Authentication
const app = new Elysia()
    .state('users', users)
    .derive({ as: 'global' }, ({ headers, store }) => {
        // Extract user from Authorization header
        const auth = headers.authorization
        let currentUser = null

        if (auth?.startsWith('Bearer ')) {
            const token = auth.slice(7)
            // Mock token validation
            currentUser = store.users.find((u: any) => u.id === token)
        }

        return { currentUser }
    })
    .use(
        graphql({
            typeDefs: gql`
                type Query {
                    me: User
                    users: [User!]
                    user(id: ID!): User
                }

                type User {
                    id: ID!
                    name: String!
                    email: String!
                    createdAt: String!
                }

                type Mutation {
                    updateProfile(name: String): User
                }
            `,
            resolvers: {
                Query: {
                    me: (_, __, { currentUser }) => currentUser,
                    users: (_, __, { store }) => store.users,
                    user: (_, { id }, { store }) =>
                        store.users.find((u: any) => u.id === id)
                },
                Mutation: {
                    updateProfile: (_, { name }, { currentUser, store }) => {
                        if (!currentUser) throw new Error('Unauthorized')
                        const user = store.users.find((u: any) => u.id === currentUser.id)
                        if (user && name) user.name = name
                        return user
                    }
                }
            }
        })
    )
    .listen(3000)

// 3. GraphQL Subscriptions
const app = new Elysia()
    .state('posts', [
        { id: '1', title: 'First Post', content: 'Hello, World!', author: 'Admin' }
    ])
    .derive({ as: 'global' }, ({ store }) => {
        const subscriptions = new Set<any>()

        return {
            subscriptions,
            notifyPostCreated(post: any) {
                subscriptions.forEach(ws => {
                    ws.send(JSON.stringify({
                        type: 'postCreated',
                        data: post
                    }))
                })
            }
        }
    })
    .use(graphql({
        typeDefs: gql`
            type Query {
                posts: [Post!]
                post(id: ID!): Post
            }

            type Mutation {
                createPost(title: String!, content: String!): Post
            }

            type Subscription {
                postCreated: Post!
            }

            type Post {
                id: ID!
                title: String!
                content: String!
                author: String!
                createdAt: String!
            }
        `,
        resolvers: {
            Query: {
                posts: (_, __, { store }) => store.posts,
                post: (_, { id }, { store }) =>
                    store.posts.find((p: any) => p.id === id)
            },
            Mutation: {
                createPost: (_, { title, content }, { store, notifyPostCreated }) => {
                    const newPost = {
                        id: (store.posts.length + 1).toString(),
                        title,
                        content,
                        author: 'Anonymous',
                        createdAt: new Date().toISOString()
                    }
                    store.posts.push(newPost)
                    notifyPostCreated(newPost)
                    return newPost
                }
            },
            Subscription: {
                postCreated: {
                    subscribe: (_, __, { subscriptions }) => {
                        const iterator = {
                            [Symbol.asyncIterator]() {
                                return this
                            },
                            async next() {
                                return { value: { postCreated: null }, done: false }
                            }
                        }
                        return iterator
                    }
                }
            }
        }
    }))
    .listen(3000)

// 4. GraphQL with DataLoader
import DataLoader from 'dataloader'

const app = new Elysia()
    .derive({ as: 'global' }, () => {
        // Create a DataLoader for batch user fetching
        const userLoader = new DataLoader(async (ids: string[]) => {
            console.log(`Batch loading users: ${ids.join(', ')}`)
            // Simulate database batch query
            return ids.map(id => users.find(u => u.id === id) || null)
        })

        return { userLoader }
    })
    .use(
        graphql({
            typeDefs: gql`
                type Query {
                    users(ids: [ID!]!): [User]
                    posts: [Post]
                }

                type User {
                    id: ID!
                    name: String!
                    email: String!
                }

                type Post {
                    id: ID!
                    title: String!
                    author: User
                    authorId: ID!
                }
            `,
            resolvers: {
                Query: {
                    users: (_, { ids }, { userLoader }) =>
                        userLoader.loadMany(ids),
                    posts: () => [
                        { id: '1', title: 'Post 1', authorId: '1' },
                        { id: '2', title: 'Post 2', authorId: '2' },
                        { id: '3', title: 'Post 3', authorId: '1' }
                    ]
                }
            },
            resolvers: {
                Post: {
                    author: (post, _, { userLoader }) =>
                        userLoader.load(post.authorId)
                }
            }
        })
    )
    .listen(3000)

// 5. GraphQL Schema Stitching
const userService = new Elysia()
    .use(
        graphql({
            typeDefs: gql`
                type Query {
                    user(id: ID!): User
                }

                type User {
                    id: ID!
                    name: String!
                    email: String!
                }
            `,
            resolvers: {
                Query: {
                    user: (_, { id }) => users.find(u => u.id === id)
                }
            }
        })
    )

const postService = new Elysia()
    .state('posts', [
        { id: '1', title: 'Post 1', authorId: '1' },
        { id: '2', title: 'Post 2', authorId: '2' }
    ])
    .use(
        graphql({
            typeDefs: gql`
                extend type Query {
                    posts: [Post!]
                }

                type Post {
                    id: ID!
                    title: String!
                    author: User
                }

                extend type User {
                    posts: [Post!]
                }
            `,
            resolvers: {
                Query: {
                    posts: (_, __, { store }) => store.posts
                },
                Post: {
                    author: (post) => ({ __typename: 'User', id: post.authorId })
                },
                User: {
                    posts: (user, _, { store }) =>
                        store.posts.filter((p: any) => p.authorId === user.id)
                }
            }
        })
    )

// 6. GraphQL Federation
const accountsService = new Elysia()
    .use(
        graphql({
            typeDefs: gql`
                type Query {
                    me: User
                }

                type User @key(fields: "id") {
                    id: ID!
                    name: String!
                }
            `,
            resolvers: {
                Query: {
                    me: () => ({ id: '1', name: 'John Doe' })
                },
                User: {
                    __resolveReference: (user) =>
                        users.find(u => u.id === user.id) || user
                }
            }
        })
    )

const postsService = new Elysia()
    .use(
        graphql({
            typeDefs: gql`
                extend type Query {
                    posts: [Post]
                }

                type Post {
                    id: ID!
                    title: String!
                    author: User
                }

                extend type User @key(fields: "id") {
                    id: ID! @external
                    posts: [Post]
                }
            `,
            resolvers: {
                Query: {
                    posts: () => [
                        { id: '1', title: 'Post 1', authorId: '1' },
                        { id: '2', title: 'Post 2', authorId: '1' }
                    ]
                },
                Post: {
                    author: (post) => ({ __typename: 'User', id: post.authorId })
                },
                User: {
                    posts: (user) => [
                        { id: '1', title: 'Post 1', authorId: user.id },
                        { id: '2', title: 'Post 2', authorId: user.id }
                    ]
                }
            }
        })
    )

// 7. GraphQL with Validation
import { z } from 'zod'

const CreateUserSchema = z.object({
    name: z.string().min(1),
    email: z.string().email()
})

const app = new Elysia()
    .use(
        graphql({
            typeDefs: gql`
                type Query {
                    users: [User!]
                }

                type Mutation {
                    createUser(input: CreateUserInput!): User!
                }

                type User {
                    id: ID!
                    name: String!
                    email: String!
                }

                input CreateUserInput {
                    name: String!
                    email: String!
                }
            `,
            resolvers: {
                Query: {
                    users: () => users
                },
                Mutation: {
                    createUser: (_, { input }) => {
                        // Validate input with Zod
                        const validatedInput = CreateUserSchema.parse(input)

                        const newUser = {
                            id: (users.length + 1).toString(),
                            ...validatedInput,
                            createdAt: new Date().toISOString()
                        }

                        users.push(newUser)
                        return newUser
                    }
                }
            }
        })
    )
    .listen(3000)

// 8. GraphQL Playground and Documentation
const app = new Elysia()
    .use(
        graphql({
            typeDefs,
            resolvers,
            playground: true, // Enable GraphQL Playground
            graphiql: true   // Enable GraphiQL interface
        })
    )
    .get('/', () => ({
        message: 'GraphQL Server',
        endpoints: {
            graphql: '/graphql',
            playground: '/graphql'
        }
    }))
    .listen(3000)

// 9. Custom Scalars
const app = new Elysia()
    .use(
        graphql({
            typeDefs: gql`
                scalar Date
                scalar Email

                type Query {
                    currentUser: User
                }

                type Mutation {
                    updateUser(birthday: Date, email: Email): User
                }

                type User {
                    id: ID!
                    name: String!
                    birthday: Date
                    email: Email
                }
            `,
            resolvers: {
                Date: {
                    serialize: (value: Date) => value.toISOString(),
                    parseValue: (value: string) => new Date(value),
                    parseLiteral: (ast: any) => new Date(ast.value)
                },
                Email: {
                    serialize: (value: string) => value,
                    parseValue: (value: string) => {
                        if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
                            throw new Error('Invalid email format')
                        }
                        return value
                    },
                    parseLiteral: (ast: any) => {
                        if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(ast.value)) {
                            throw new Error('Invalid email format')
                        }
                        return ast.value
                    }
                },
                Query: {
                    currentUser: () => ({
                        id: '1',
                        name: 'John Doe',
                        birthday: new Date('1990-01-01'),
                        email: '[email protected]'
                    })
                },
                Mutation: {
                    updateUser: (_, { birthday, email }) => ({
                        id: '1',
                        name: 'John Doe',
                        birthday,
                        email
                    })
                }
            }
        })
    )
    .listen(3000)

// 10. GraphQL Error Handling
const app = new Elysia()
    .use(
        graphql({
            typeDefs: gql`
                type Query {
                    user(id: ID!): User
                    throwError: String
                }

                type User {
                    id: ID!
                    name: String!
                }
            `,
            resolvers: {
                Query: {
                    user: (_, { id }) => {
                        const user = users.find(u => u.id === id)
                        if (!user) {
                            throw new GraphQLError('User not found', {
                                extensions: { code: 'USER_NOT_FOUND' }
                            })
                        }
                        return user
                    },
                    throwError: () => {
                        throw new GraphQLError('This is a test error', {
                            extensions: {
                                code: 'TEST_ERROR',
                                details: 'Additional error information'
                            }
                        })
                    }
                }
            },
            context: () => ({}),
            formatError: (error) => {
                console.error('GraphQL Error:', error)
                return {
                    message: error.message,
                    code: error.extensions?.code,
                    details: error.extensions?.details,
                    path: error.path,
                    locations: error.locations
                }
            }
        })
    )
    .listen(3000)

💻 Elysia.js Plugin Development typescript

🔴 complex

Creating custom plugins and using ecosystem plugins

// Elysia.js Plugin Development Examples

import { Elysia } from 'elysia'

// 1. Basic custom plugin
const timestampPlugin = new Elysia({ name: 'timestamp' })
    .decorate('getTimestamp', () => new Date().toISOString())
    .onBeforeHandle({ as: 'global' }, ({ set, getTimestamp }) => {
        set.headers['X-Timestamp'] = getTimestamp()
    })

// Using the plugin
const app = new Elysia()
    .use(timestampPlugin)
    .get('/time', ({ getTimestamp }) => getTimestamp())
    .listen(3000)

// 2. Database plugin
interface Database {
    query: (sql: string, params?: any[]) => Promise<any[]>
    insert: (table: string, data: any) => Promise<any>
    update: (table: string, id: string, data: any) => Promise<any>
    delete: (table: string, id: string) => Promise<boolean>
}

const databasePlugin = new Elysia({ name: 'database' })
    .derive({ as: 'global' }, () => {
        // Mock database implementation
        const database: Database = {
            async query(sql: string, params: any[] = []) {
                console.log(`Query: ${sql}`, params)
                // Mock data
                return [{ id: 1, name: 'John', email: '[email protected]' }]
            },
            async insert(table: string, data: any) {
                console.log(`Insert into ${table}:`, data)
                return { id: Date.now(), ...data }
            },
            async update(table: string, id: string, data: any) {
                console.log(`Update ${table} ${id}:`, data)
                return { id, ...data }
            },
            async delete(table: string, id: string) {
                console.log(`Delete from ${table} where id=${id}`)
                return true
            }
        }

        return { database }
    })

// Using database plugin
const app = new Elysia()
    .use(databasePlugin)
    .get('/users', async ({ database }) => {
        const users = await database.query('SELECT * FROM users')
        return users
    })
    .post('/users', async ({ body, database }) => {
        const user = await database.insert('users', body)
        return user
    })
    .listen(3000)

// 3. Caching plugin
const cachePlugin = new Elysia({ name: 'cache' })
    .derive({ as: 'global' }, () => {
        const cache = new Map<string, { data: any; expiry: number }>()

        return {
            cache: {
                get(key: string) {
                    const item = cache.get(key)
                    if (!item || Date.now() > item.expiry) {
                        cache.delete(key)
                        return null
                    }
                    return item.data
                },
                set(key: string, data: any, ttl: number = 60000) {
                    cache.set(key, {
                        data,
                        expiry: Date.now() + ttl
                    })
                },
                clear() {
                    cache.clear()
                }
            }
        }
    })

const app = new Elysia()
    .use(cachePlugin)
    .get('/expensive', async ({ cache }) => {
        const cacheKey = 'expensive-data'
        let data = cache.get(cacheKey)

        if (!data) {
            // Simulate expensive operation
            await new Promise(resolve => setTimeout(resolve, 2000))
            data = { message: 'Expensive data', timestamp: Date.now() }
            cache.set(cacheKey, data, 10000) // Cache for 10 seconds
        }

        return data
    })
    .listen(3000)

// 4. Configuration plugin
interface AppConfig {
    database: {
        url: string
        maxConnections: number
    }
    auth: {
        jwtSecret: string
        expiresIn: string
    }
    server: {
        port: number
        host: string
    }
}

const configPlugin = new Elysia({ name: 'config' })
    .derive({ as: 'global' }, () => {
        const config: AppConfig = {
            database: {
                url: process.env.DB_URL || 'sqlite:app.db',
                maxConnections: parseInt(process.env.DB_MAX_CONN || '10')
            },
            auth: {
                jwtSecret: process.env.JWT_SECRET || 'default-secret',
                expiresIn: process.env.JWT_EXPIRES_IN || '1h'
            },
            server: {
                port: parseInt(process.env.PORT || '3000'),
                host: process.env.HOST || 'localhost'
            }
        }

        return { config }
    })

const app = new Elysia()
    .use(configPlugin)
    .get('/config', ({ config }) => config)
    .listen(3000)

// 5. Logging plugin
const loggerPlugin = new Elysia({ name: 'logger' })
    .derive({ as: 'global' }, () => {
        const logLevels = ['debug', 'info', 'warn', 'error'] as const

        const logger = {
            debug: (message: string, ...args: any[]) => {
                console.debug(`[DEBUG] ${new Date().toISOString()} - ${message}`, ...args)
            },
            info: (message: string, ...args: any[]) => {
                console.info(`[INFO] ${new Date().toISOString()} - ${message}`, ...args)
            },
            warn: (message: string, ...args: any[]) => {
                console.warn(`[WARN] ${new Date().toISOString()} - ${message}`, ...args)
            },
            error: (message: string, ...args: any[]) => {
                console.error(`[ERROR] ${new Date().toISOString()} - ${message}`, ...args)
            }
        }

        return { logger }
    })
    .onBeforeHandle({ as: 'global' }, ({ logger, request }) => {
        logger.info(`${request.method} ${request.url}`)
    })
    .onError({ as: 'global' }, ({ logger, error }) => {
        logger.error(error.message)
    })

const app = new Elysia()
    .use(loggerPlugin)
    .get('/logged', ({ logger }) => {
        logger.info('This is an info message')
        logger.warn('This is a warning')
        return 'Logged response'
    })
    .listen(3000)

// 6. Plugin with lifecycle
interface User {
    id: number
    name: string
    email: string
}

const userPlugin = new Elysia({ name: 'user' })
    .derive({ as: 'global' }, ({ headers }) => {
        const authHeader = headers.authorization

        // Extract user from JWT (simplified)
        const getUser = (): User | null => {
            if (!authHeader) return null

            // In real app, decode JWT here
            return {
                id: 1,
                name: 'John Doe',
                email: '[email protected]'
            }
        }

        return {
            getUser,
            requireAuth(): User {
                const user = getUser()
                if (!user) throw new Error('Unauthorized')
                return user
            }
        }
    })
    .onBeforeHandle({ as: 'global' }, ({ set, getUser }) => {
        const user = getUser()
        if (user) {
            set.headers['X-User-ID'] = user.id.toString()
        }
    })

const app = new Elysia()
    .use(userPlugin)
    .get('/profile', ({ getUser }) => {
        const user = getUser()
        return user || { message: 'Not authenticated' }
    })
    .get('/protected', ({ requireAuth }) => {
        const user = requireAuth()
        return `Welcome, ${user.name}!`
    })
    .listen(3000)

// 7. Plugin composition
const basePlugin = new Elysia({ name: 'base' })
    .decorate('baseMethod', () => 'Base functionality')
    .state('baseState', 'Base state')

const extendedPlugin = new Elysia({ name: 'extended' })
    .use(basePlugin)
    .decorate('extendedMethod', ({ baseMethod }) => `${baseMethod} + Extended`)
    .state('extendedState', 'Extended state')

const app = new Elysia()
    .use(extendedPlugin)
    .get('/composed', ({ baseMethod, extendedMethod, store: { baseState, extendedState } }) => ({
        baseMethod,
        extendedMethod,
        baseState,
        extendedState
    }))
    .listen(3000)

// 8. Plugin with options
interface RateLimitOptions {
    windowMs: number
    maxRequests: number
    message?: string
}

const rateLimitPlugin = (options: RateLimitOptions) => {
    const requests = new Map<string, { count: number; resetTime: number }>()

    return new Elysia({ name: 'rate-limit' })
        .onBeforeHandle({ as: 'global' }, ({ set, headers }) => {
            const key = headers['x-forwarded-for'] || 'default'
            const now = Date.now()

            const record = requests.get(key)

            if (!record || now > record.resetTime) {
                requests.set(key, { count: 1, resetTime: now + options.windowMs })
                return
            }

            if (record.count >= options.maxRequests) {
                set.status = 429
                return options.message || 'Too many requests'
            }

            record.count++
        })
}

const app = new Elysia()
    .use(rateLimitPlugin({ windowMs: 60000, maxRequests: 10, message: 'Rate limit exceeded' }))
    .get('/limited', () => 'Rate limited endpoint')
    .listen(3000)

// 9. Third-party plugin example (JWT)
// npm install @elysiajs/jwt
import { jwt } from '@elysiajs/jwt'

const app = new Elysia()
    .use(
        jwt({
            name: 'jwt',
            secret: process.env.JWT_SECRET || 'default-secret'
        })
    )
    .post('/login', async ({ body, jwt }) => {
        // Validate credentials (simplified)
        if (body.username === 'admin' && body.password === 'password') {
            const token = await jwt.sign({
                sub: 'user123',
                name: 'Admin User'
            })
            return { token }
        }

        throw new Error('Invalid credentials')
    })
    .get('/profile', async ({ jwt, headers }) => {
        const auth = headers.authorization
        if (!auth) throw new Error('No token provided')

        const token = auth.replace('Bearer ', '')
        const payload = await jwt.verify(token)

        return payload
    })
    .listen(3000)

// 10. Plugin with external dependencies
// npm install ioredis
import Redis from 'ioredis'

const redisPlugin = new Elysia({ name: 'redis' })
    .derive({ as: 'global' }, async () => {
        const redis = new Redis({
            host: process.env.REDIS_HOST || 'localhost',
            port: parseInt(process.env.REDIS_PORT || '6379')
        })

        return {
            redis: {
                async get(key: string): Promise<string | null> {
                    return await redis.get(key)
                },
                async set(key: string, value: string, ttl?: number): Promise<void> {
                    if (ttl) {
                        await redis.setex(key, ttl, value)
                    } else {
                        await redis.set(key, value)
                    }
                },
                async del(key: string): Promise<boolean> {
                    const result = await redis.del(key)
                    return result > 0
                }
            }
        }
    })

const app = new Elysia()
    .use(redisPlugin)
    .post('/cache/:key', async ({ params: { key }, body, redis }) => {
        await redis.set(key, JSON.stringify(body), 3600)
        return { cached: true, key }
    })
    .get('/cache/:key', async ({ params: { key }, redis }) => {
        const value = await redis.get(key)
        return value ? JSON.parse(value) : null
    })
    .listen(3000)