Exemplos Deno

Exemplos do runtime Deno incluindo servidor HTTP, WebSocket, framework Oak e NanoJS

💻 Deno Hello World typescript

🟢 simple

Configuração básica do servidor HTTP Deno e aplicação Hello World

// Deno Hello World Examples

// 1. Basic HTTP server using std/http
import { serve } from "https://deno.land/[email protected]/http/server.ts";

async function handler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    switch (url.pathname) {
        case '/':
            return new Response("Hello, World!");
        case '/hello':
            return new Response("Hello from Deno!");
        case '/hello/:name':
            const name = url.pathname.split('/')[2];
            return new Response(`Hello, ${name}!`);
        default:
            return new Response("Not Found", { status: 404 });
    }
}

console.log("Listening on http://localhost:8000");
await serve(handler, { port: 8000 });

// 2. JSON response
async function handler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    if (url.pathname === '/api/hello') {
        return Response.json({
            message: 'Hello, World!',
            timestamp: new Date().toISOString(),
            version: '1.0.0',
            runtime: 'Deno'
        });
    }

    return new Response('Hello, World!');
}

// 3. HTTP methods handling
async function handler(req: Request): Promise<Response> {
    const url = new URL(req.url);
    const method = req.method;

    if (url.pathname === '/api/users') {
        switch (method) {
            case 'GET':
                return Response.json(['Alice', 'Bob', 'Charlie']);
            case 'POST':
                return new Response('User created', { status: 201 });
            default:
                return new Response('Method Not Allowed', { status: 405 });
        }
    }

    return new Response('Hello, World!');
}

// 4. Request body parsing
async function handler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    if (url.pathname === '/api/hello' && req.method === 'POST') {
        const body = await req.json();
        return Response.json({
            greeting: `Hello, ${body.name || 'World'}!`,
            message: body.message || 'Welcome to Deno',
            receivedAt: new Date().toISOString()
        });
    }

    return new Response('Hello, World!');
}

// 5. HTML response
async function handler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    if (url.pathname === '/') {
        const html = `
            <!DOCTYPE html>
            <html>
            <head>
                <title>Hello Deno</title>
            </head>
            <body>
                <h1>Hello, World!</h1>
                <p>This is an HTML response from Deno</p>
            </body>
            </html>
        `;
        return new Response(html, {
            headers: { 'Content-Type': 'text/html' }
        });
    }

    return new Response('Hello, World!');
}

// 6. Error handling
async function handler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    if (url.pathname === '/error') {
        throw new Error('Something went wrong!');
    }

    return new Response('Hello, World!');
}

// Run with error handling
try {
    await serve(handler, { port: 8000 });
} catch (error) {
    console.error('Server error:', error);
}

// 7. File serving
import { dirname, join } from "https://deno.land/[email protected]/path/mod.ts";

async function fileHandler(req: Request): Promise<Response> {
    const url = new URL(req.url);
    const filePath = url.pathname === '/' ? './public/index.html' : `./public${url.pathname}`;

    try {
        const file = await Deno.open(filePath);
        const fileInfo = await file.stat();

        if (fileInfo.isDirectory) {
            file.close();
            const indexPath = join(filePath, 'index.html');
            const indexFile = await Deno.open(indexPath);
            return new Response(indexFile.readable);
        }

        return new Response(file.readable);
    } catch (error) {
        return new Response('File not found', { status: 404 });
    }
}

console.log("File server listening on http://localhost:8000");
await serve(fileHandler, { port: 8000 });

// 8. Streaming response
async function streamingHandler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    if (url.pathname === '/stream') {
        const encoder = new TextEncoder();
        const readable = new ReadableStream({
            start(controller) {
                let count = 0;
                const interval = setInterval(() => {
                    controller.enqueue(encoder.encode(`data: Message ${count++}\n\n`));
                    if (count >= 10) {
                        clearInterval(interval);
                        controller.close();
                    }
                }, 1000);
            }
        });

        return new Response(readable, {
            headers: {
                'Content-Type': 'text/event-stream',
                'Cache-Control': 'no-cache',
                'Connection': 'keep-alive'
            }
        });
    }

    return new Response('Hello, World!');
}

console.log("Streaming server listening on http://localhost:8000");
await serve(streamingHandler, { port: 8000 });

💻 Framework Oak Deno typescript

🟡 intermediate

Desenvolvimento de aplicações web usando o framework Oak para Deno

// Deno Oak Framework Examples

// 1. Basic Oak application
import { Application, Router } from "https://deno.land/x/[email protected]/mod.ts";

const app = new Application();
const router = new Router();

// Basic routes
router.get("/", (ctx) => {
    ctx.response.body = "Hello, Oak!";
});

router.get("/hello/:name", (ctx) => {
    const { name } = ctx.params;
    ctx.response.body = `Hello, ${name}!`;
});

app.use(router.routes());
app.use(router.allowedMethods());

console.log("Oak server listening on http://localhost:8000");
await app.listen({ port: 8000 });

// 2. Oak with middleware
import { Application, Router, Context } from "https://deno.land/x/[email protected]/mod.ts";

const app = new Application();

// Logger middleware
app.use(async (ctx, next) => {
    await next();
    const rt = ctx.response.headers.get("X-Response-Time");
    console.log(`${ctx.request.method} ${ctx.request.url} - ${rt}`);
});

// Timing middleware
app.use(async (ctx, next) => {
    const start = Date.now();
    await next();
    const ms = Date.now() - start;
    ctx.response.headers.set("X-Response-Time", `${ms}ms`);
});

// CORS middleware
app.use(async (ctx, next) => {
    ctx.response.headers.set("Access-Control-Allow-Origin", "*");
    ctx.response.headers.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    ctx.response.headers.set("Access-Control-Allow-Headers", "Content-Type, Authorization");
    await next();
});

// Router with routes
const router = new Router();

router.get("/", (ctx) => {
    ctx.response.body = {
        message: "Hello from Oak!",
        timestamp: new Date().toISOString()
    };
});

router.get("/api/users", (ctx) => {
    ctx.response.body = [
        { id: 1, name: "John Doe", email: "[email protected]" },
        { id: 2, name: "Jane Smith", email: "[email protected]" }
    ];
});

router.post("/api/users", async (ctx) => {
    const body = ctx.request.body({ type: "json" });
    const user = await body.value;

    ctx.response.body = {
        id: 3,
        ...user,
        createdAt: new Date().toISOString()
    };
    ctx.response.status = 201;
});

app.use(router.routes());
app.use(router.allowedMethods());

// Error handling middleware
app.use(async (ctx, next) => {
    try {
        await next();
    } catch (err) {
        console.error(err);
        ctx.response.status = 500;
        ctx.response.body = { error: "Internal Server Error" };
    }
});

console.log("Oak server with middleware listening on http://localhost:8000");
await app.listen({ port: 8000 });

// 3. Oak with static files and templates
import { Application, Router } from "https://deno.land/x/[email protected]/mod.ts";

const app = new Application();
const router = new Router();

// Template function
function renderTemplate(template: string, data: Record<string, any> = {}): string {
    return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
        return data[key] || match;
    });
}

// HTML template
const indexTemplate = `
<!DOCTYPE html>
<html>
<head>
    <title>{{title}}</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; }
        .container { max-width: 800px; margin: 0 auto; }
        .user { border: 1px solid #ddd; padding: 10px; margin: 10px 0; }
    </style>
</head>
<body>
    <div class="container">
        <h1>{{title}}</h1>
        <p>{{message}}</p>
        <div class="users">
            {{users}}
        </div>
    </div>
</body>
</html>
`;

// Routes
router.get("/", async (ctx) => {
    const html = renderTemplate(indexTemplate, {
        title: "Oak Demo",
        message: "Welcome to Oak framework with Deno!",
        users: `
            <div class="user">
                <h3>John Doe</h3>
                <p>Email: [email protected]</p>
            </div>
            <div class="user">
                <h3>Jane Smith</h3>
                <p>Email: [email protected]</p>
            </div>
        `
    });

    ctx.response.body = html;
    ctx.response.headers.set("Content-Type", "text/html");
});

router.get("/api/data", (ctx) => {
    ctx.response.body = {
        users: [
            { id: 1, name: "John Doe", email: "[email protected]" },
            { id: 2, name: "Jane Smith", email: "[email protected]" }
        ],
        timestamp: new Date().toISOString()
    };
});

// Static file serving
app.use(async (ctx, next) => {
    const path = ctx.request.url.pathname;

    if (path.startsWith("/static/")) {
        try {
            const file = await Deno.open(`.${path}`);
            ctx.response.body = file.readable;
            return;
        } catch (error) {
            // File not found, continue to next middleware
        }
    }

    await next();
});

app.use(router.routes());
app.use(router.allowedMethods());

console.log("Oak server with templates listening on http://localhost:8000");
await app.listen({ port: 8000 });

// 4. Oak REST API with authentication middleware
import { Application, Router, Context } from "https://deno.land/x/[email protected]/mod.ts";
import { create, verify } from "https://deno.land/x/[email protected]/mod.ts";

interface User {
    id: number;
    name: string;
    email: string;
    role: string;
}

const users: User[] = [
    { id: 1, name: "John Doe", email: "[email protected]", role: "admin" },
    { id: 2, name: "Jane Smith", email: "[email protected]", role: "user" }
];

const JWT_SECRET = "your-secret-key";

const app = new Application();
const router = new Router();

// Authentication middleware
async function jwtAuthMiddleware(ctx: Context, next: () => Promise<void>) {
    const authHeader = ctx.request.headers.get("Authorization");

    if (!authHeader?.startsWith("Bearer ")) {
        ctx.response.status = 401;
        ctx.response.body = { error: "No token provided" };
        return;
    }

    const token = authHeader.slice(7);

    try {
        const payload = await verify(token, JWT_SECRET);
        ctx.state.user = payload;
        await next();
    } catch (error) {
        ctx.response.status = 401;
        ctx.response.body = { error: "Invalid token" };
    }
}

// Role-based authorization middleware
function roleMiddleware(requiredRole: string) {
    return async (ctx: Context, next: () => Promise<void>) => {
        const user = ctx.state.user;

        if (!user || user.role !== requiredRole) {
            ctx.response.status = 403;
            ctx.response.body = { error: "Insufficient permissions" };
            return;
        }

        await next();
    };
}

// Public routes
router.post("/auth/login", async (ctx) => {
    const { email, password } = await ctx.request.body({ type: "json" }).value;

    // Mock authentication
    if (email === "[email protected]" && password === "password") {
        const user = users.find(u => u.email === email);
        const jwt = await create({ alg: "HS256", typ: "JWT" }, { ...user }, JWT_SECRET);

        ctx.response.body = { token: jwt, user };
    } else {
        ctx.response.status = 401;
        ctx.response.body = { error: "Invalid credentials" };
    }
});

// Protected routes
router.get("/api/users", jwtAuthMiddleware, (ctx) => {
    ctx.response.body = users;
});

router.get("/api/users/:id", jwtAuthMiddleware, (ctx) => {
    const id = parseInt(ctx.params.id!);
    const user = users.find(u => u.id === id);

    if (!user) {
        ctx.response.status = 404;
        ctx.response.body = { error: "User not found" };
        return;
    }

    ctx.response.body = user;
});

router.delete("/api/users/:id", jwtAuthMiddleware, roleMiddleware("admin"), (ctx) => {
    const id = parseInt(ctx.params.id!);
    const index = users.findIndex(u => u.id === id);

    if (index === -1) {
        ctx.response.status = 404;
        ctx.response.body = { error: "User not found" };
        return;
    }

    users.splice(index, 1);
    ctx.response.body = { message: "User deleted successfully" };
});

app.use(router.routes());
app.use(router.allowedMethods());

console.log("Oak API server with auth listening on http://localhost:8000");
await app.listen({ port: 8000 });

💻 Framework NanoJS Deno typescript

🟡 intermediate

Framework web leve NanoJS para aplicações Deno

// Deno NanoJS Framework Examples

// 1. Basic NanoJS application
import { nanoServer } from "https://deno.land/x/[email protected]/mod.ts";

const server = nanoServer();

// GET routes
server.get("/", () => "Hello, NanoJS!");

server.get("/hello/:name", (req) => {
    return `Hello, ${req.params.name}!`;
});

server.get("/api/hello", () => {
    return {
        message: "Hello, World!",
        timestamp: new Date().toISOString(),
        framework: "NanoJS"
    };
});

// POST routes
server.post("/api/hello", (req) => {
    return {
        greeting: `Hello, ${req.body.name || 'World'}!`,
        message: req.body.message || "Welcome to NanoJS"
    };
});

// Start server
server.listen({ port: 8000 });
console.log("NanoJS server listening on http://localhost:8000");

// 2. NanoJS with middleware
import { nanoServer } from "https://deno.land/x/[email protected]/mod.ts";

const server = nanoServer();

// Logger middleware
server.use((req, res, next) => {
    console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
    next();
});

// CORS middleware
server.use((req, res, next) => {
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
    next();
});

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

server.use((req, res, next) => {
    const ip = req.headers.get("x-forwarded-for") || "127.0.0.1";
    const now = Date.now();
    const windowMs = 60000; // 1 minute
    const maxRequests = 100;

    const record = requests.get(ip);

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

    if (record.count >= maxRequests) {
        res.status = 429;
        res.body = { error: "Too Many Requests" };
        return;
    }

    record.count++;
    next();
});

// Routes
server.get("/", () => "Hello, NanoJS with middleware!");

server.get("/api/users", () => {
    return [
        { id: 1, name: "John Doe", email: "[email protected]" },
        { id: 2, name: "Jane Smith", email: "[email protected]" }
    ];
});

server.post("/api/users", (req) => {
    const newUser = {
        id: Date.now(),
        ...req.body,
        createdAt: new Date().toISOString()
    };

    return { message: "User created", user: newUser };
});

server.listen({ port: 8000 });
console.log("NanoJS server with middleware listening on http://localhost:8000");

// 3. NanoJS REST API with validation
import { nanoServer } from "https://deno.land/x/[email protected]/mod.ts";

const server = nanoServer();

// Validation middleware
function validateBody(schema: Record<string, any>) {
    return (req: any, res: any, next: any) => {
        const errors: string[] = [];

        for (const [key, rules] of Object.entries(schema)) {
            const value = req.body[key];

            if (rules.required && (value === undefined || value === null)) {
                errors.push(`${key} is required`);
                continue;
            }

            if (value !== undefined && rules.type && typeof value !== rules.type) {
                errors.push(`${key} must be of type ${rules.type}`);
            }

            if (rules.minLength && value && value.length < rules.minLength) {
                errors.push(`${key} must be at least ${rules.minLength} characters`);
            }

            if (rules.pattern && value && !rules.pattern.test(value)) {
                errors.push(`${key} format is invalid`);
            }
        }

        if (errors.length > 0) {
            res.status = 400;
            res.body = { errors };
            return;
        }

        next();
    };
}

// User schema
const userSchema = {
    name: { required: true, type: "string", minLength: 2 },
    email: {
        required: true,
        type: "string",
        pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
    },
    age: { type: "number", minimum: 18 }
};

// In-memory users database
let users = [
    { id: 1, name: "John Doe", email: "[email protected]", age: 30 },
    { id: 2, name: "Jane Smith", email: "[email protected]", age: 25 }
];

let userIdCounter = 3;

// API Routes
server.get("/api/users", (req, res) => {
    const page = parseInt(req.query.page || "1");
    const limit = parseInt(req.query.limit || "10");
    const search = req.query.search;

    let filteredUsers = users;

    if (search) {
        filteredUsers = users.filter(user =>
            user.name.toLowerCase().includes(search.toLowerCase()) ||
            user.email.toLowerCase().includes(search.toLowerCase())
        );
    }

    const startIndex = (page - 1) * limit;
    const endIndex = startIndex + limit;
    const paginatedUsers = filteredUsers.slice(startIndex, endIndex);

    res.body = {
        users: paginatedUsers,
        pagination: {
            page,
            limit,
            total: filteredUsers.length,
            pages: Math.ceil(filteredUsers.length / limit)
        }
    };
});

server.get("/api/users/:id", (req, res) => {
    const id = parseInt(req.params.id);
    const user = users.find(u => u.id === id);

    if (!user) {
        res.status = 404;
        res.body = { error: "User not found" };
        return;
    }

    res.body = user;
});

server.post("/api/users", validateBody(userSchema), (req, res) => {
    const newUser = {
        id: userIdCounter++,
        ...req.body,
        createdAt: new Date().toISOString()
    };

    users.push(newUser);
    res.status = 201;
    res.body = { message: "User created", user: newUser };
});

server.put("/api/users/:id", validateBody(userSchema), (req, res) => {
    const id = parseInt(req.params.id);
    const userIndex = users.findIndex(u => u.id === id);

    if (userIndex === -1) {
        res.status = 404;
        res.body = { error: "User not found" };
        return;
    }

    users[userIndex] = { ...users[userIndex], ...req.body };
    res.body = { message: "User updated", user: users[userIndex] };
});

server.delete("/api/users/:id", (req, res) => {
    const id = parseInt(req.params.id);
    const userIndex = users.findIndex(u => u.id === id);

    if (userIndex === -1) {
        res.status = 404;
        res.body = { error: "User not found" };
        return;
    }

    const deletedUser = users.splice(userIndex, 1)[0];
    res.body = { message: "User deleted", user: deletedUser };
});

// Health check
server.get("/health", (req, res) => {
    res.body = {
        status: "ok",
        timestamp: new Date().toISOString(),
        uptime: Deno.stdout?.rid || 0,
        stats: {
            users: users.length
        }
    };
});

server.listen({ port: 8000 });
console.log("NanoJS REST API listening on http://localhost:8000");

// 4. NanoJS with WebSocket support
import { nanoServer } from "https://deno.land/x/[email protected]/mod.ts";

const server = nanoServer();

// WebSocket upgrade handling
server.upgrade("/ws", (req, socket) => {
    console.log("WebSocket connection established");

    socket.addEventListener("message", (event) => {
        console.log("Received:", event.data);
        socket.send(`Echo: ${event.data}`);
    });

    socket.addEventListener("close", () => {
        console.log("WebSocket connection closed");
    });

    socket.send("Welcome to NanoJS WebSocket server!");
});

// Regular HTTP routes
server.get("/", () => `
    <!DOCTYPE html>
    <html>
    <head>
        <title>NanoJS WebSocket Demo</title>
    </head>
    <body>
        <h1>NanoJS WebSocket Demo</h1>
        <input type="text" id="messageInput" placeholder="Type a message...">
        <button onclick="sendMessage()">Send</button>
        <div id="messages"></div>

        <script>
            const ws = new WebSocket('ws://localhost:8000/ws');
            const messagesDiv = document.getElementById('messages');
            const messageInput = document.getElementById('messageInput');

            ws.onmessage = function(event) {
                const message = document.createElement('div');
                message.textContent = event.data;
                messagesDiv.appendChild(message);
            };

            function sendMessage() {
                const message = messageInput.value;
                if (message) {
                    ws.send(message);
                    messageInput.value = '';
                }
            }

            messageInput.addEventListener('keypress', function(e) {
                if (e.key === 'Enter') {
                    sendMessage();
                }
            });
        </script>
    </body>
    </html>
`);

server.get("/api/status", () => {
    return {
        message: "NanoJS server with WebSocket support",
        websocket: "ws://localhost:8000/ws",
        timestamp: new Date().toISOString()
    };
});

server.listen({ port: 8000 });
console.log("NanoJS server with WebSocket listening on http://localhost:8000");

💻 Servidor WebSocket Deno typescript

🟡 intermediate

Implementação de servidor WebSocket usando Deno e a biblioteca padrão WebSocket

// Deno WebSocket Server Examples

// 1. Basic WebSocket server
import { serve } from "https://deno.land/[email protected]/http/server.ts";

async function handler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    if (url.pathname === "/ws") {
        const upgrade = req.headers.get("upgrade") || "";
        if (upgrade.toLowerCase() !== "websocket") {
            return new Response("Expected websocket", { status: 426 });
        }

        const { socket, response } = Deno.upgradeWebSocket(req);

        socket.onopen = () => {
            console.log("WebSocket connection opened");
            socket.send("Welcome to Deno WebSocket server!");
        };

        socket.onmessage = (event) => {
            console.log("Received:", event.data);
            socket.send(`Echo: ${event.data}`);
        };

        socket.onclose = () => {
            console.log("WebSocket connection closed");
        };

        socket.onerror = (error) => {
            console.error("WebSocket error:", error);
        };

        return response;
    }

    return new Response("WebSocket server running");
}

console.log("WebSocket server listening on http://localhost:8000");
await serve(handler, { port: 8000 });

// 2. Chat server with multiple clients
import { serve } from "https://deno.land/[email protected]/http/server.ts";

interface Message {
    type: "message" | "join" | "leave";
    user: string;
    content: string;
    timestamp: string;
}

const clients = new Map<string, WebSocket>();

async function chatHandler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    if (url.pathname === "/chat") {
        const upgrade = req.headers.get("upgrade") || "";
        if (upgrade.toLowerCase() !== "websocket") {
            return new Response("Expected websocket", { status: 426 });
        }

        const { socket, response } = Deno.upgradeWebSocket(req);
        const userId = `user_${Math.random().toString(36).substr(2, 9)}`;

        clients.set(userId, socket);

        // Send join message to all clients
        broadcast({
            type: "join",
            user: "System",
            content: `${userId} joined the chat`,
            timestamp: new Date().toISOString()
        });

        socket.onopen = () => {
            console.log(`${userId} connected`);
            socket.send(`Welcome to the chat! Your ID: ${userId}`);
        };

        socket.onmessage = (event) => {
            const message: Message = {
                type: "message",
                user: userId,
                content: event.data,
                timestamp: new Date().toISOString()
            };

            broadcast(message);
            console.log(`${userId}: ${event.data}`);
        };

        socket.onclose = () => {
            clients.delete(userId);
            console.log(`${userId} disconnected`);

            // Send leave message to all clients
            broadcast({
                type: "leave",
                user: "System",
                content: `${userId} left the chat`,
                timestamp: new Date().toISOString()
            });
        };

        return response;
    }

    // Serve HTML page for chat
    if (url.pathname === "/") {
        return new Response(`
            <!DOCTYPE html>
            <html>
            <head>
                <title>Deno WebSocket Chat</title>
                <style>
                    body { font-family: Arial, sans-serif; margin: 20px; }
                    #messages {
                        border: 1px solid #ccc;
                        height: 400px;
                        overflow-y: scroll;
                        padding: 10px;
                        margin: 10px 0;
                    }
                    #input {
                        width: 70%;
                        padding: 5px;
                    }
                    #send {
                        width: 25%;
                        padding: 5px;
                    }
                    .join { color: green; }
                    .leave { color: red; }
                </style>
            </head>
            <body>
                <h1>Deno WebSocket Chat</h1>
                <div id="messages"></div>
                <input type="text" id="input" placeholder="Type a message...">
                <button id="send">Send</button>

                <script>
                    const ws = new WebSocket('ws://localhost:8000/chat');
                    const messages = document.getElementById('messages');
                    const input = document.getElementById('input');
                    const send = document.getElementById('send');

                    ws.onmessage = function(event) {
                        const data = JSON.parse(event.data);
                        const message = document.createElement('div');
                        message.className = data.type;
                        message.innerHTML = `
                            <strong>${data.user}:</strong>
                            ${data.content}
                            <small>(${new Date(data.timestamp).toLocaleTimeString()})</small>
                        `;
                        messages.appendChild(message);
                        messages.scrollTop = messages.scrollHeight;
                    };

                    function sendMessage() {
                        const text = input.value.trim();
                        if (text) {
                            ws.send(text);
                            input.value = '';
                        }
                    }

                    send.onclick = sendMessage;
                    input.onkeypress = function(e) {
                        if (e.key === 'Enter') sendMessage();
                    };
                </script>
            </body>
            </html>
        `, {
            headers: { "Content-Type": "text/html" }
        });
    }

    return new Response("Chat server running", { status: 404 });
}

function broadcast(message: Message) {
    const messageStr = JSON.stringify(message);
    clients.forEach((client) => {
        client.send(messageStr);
    });
}

console.log("Chat server listening on http://localhost:8000");
await serve(chatHandler, { port: 8000 });

// 3. Real-time notifications server
import { serve } from "https://deno.land/[email protected]/http/server.ts";

interface Notification {
    type: "notification" | "alert" | "update";
    title: string;
    message: string;
    timestamp: string;
}

const notificationClients = new Set<WebSocket>();

async function notificationHandler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    if (url.pathname === "/notifications") {
        const upgrade = req.headers.get("upgrade") || "";
        if (upgrade.toLowerCase() !== "websocket") {
            return new Response("Expected websocket", { status: 426 });
        }

        const { socket, response } = Deno.upgradeWebSocket(req);

        notificationClients.add(socket);

        socket.onopen = () => {
            console.log("Notification client connected");

            // Send periodic notifications
            const interval = setInterval(() => {
                const notifications: Notification[] = [
                    { type: "notification", title: "System Update", message: `Server time: ${new Date().toLocaleTimeString()}`, timestamp: new Date().toISOString() },
                    { type: "alert", title: "Security Alert", message: "Security scan completed successfully", timestamp: new Date().toISOString() },
                    { type: "update", title: "New Feature", message: "Check out our latest updates!", timestamp: new Date().toISOString() }
                ];

                const notification = notifications[Math.floor(Math.random() * notifications.length)];

                notificationClients.forEach(client => {
                    client.send(JSON.stringify(notification));
                });
            }, 5000);

            socket.data.interval = interval;
        };

        socket.onclose = () => {
            notificationClients.delete(socket);
            if (socket.data.interval) {
                clearInterval(socket.data.interval);
            }
        };

        return response;
    }

    // API to send custom notifications
    if (url.pathname === "/api/notify" && req.method === "POST") {
        const body = await req.json();
        const notification: Notification = {
            type: body.type || "notification",
            title: body.title,
            message: body.message,
            timestamp: new Date().toISOString()
        };

        notificationClients.forEach(client => {
            client.send(JSON.stringify(notification));
        });

        return Response.json({ success: true, notification });
    }

    return new Response("Notification server running");
}

console.log("Notification server listening on http://localhost:8000");
await serve(notificationHandler, { port: 8000 });

// 4. WebSocket with authentication
import { serve } from "https://deno.land/[email protected]/http/server.ts";
import { create, verify } from "https://deno.land/x/[email protected]/mod.ts";

const JWT_SECRET = "your-secret-key";

async function authHandler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    // Login endpoint to get token
    if (url.pathname === "/login" && req.method === "POST") {
        const { username, password } = await req.json();

        // Mock authentication
        if (username === "admin" && password === "password") {
            const token = await create(
                { alg: "HS256", typ: "JWT" },
                { username, role: "admin" },
                JWT_SECRET
            );

            return Response.json({ token });
        }

        return Response.json({ error: "Invalid credentials" }, { status: 401 });
    }

    if (url.pathname === "/protected-ws") {
        const authHeader = req.headers.get("authorization");
        if (!authHeader?.startsWith("Bearer ")) {
            return new Response("Unauthorized", { status: 401 });
        }

        const token = authHeader.slice(7);

        try {
            const payload = await verify(token, JWT_SECRET);
            console.log("Authenticated user:", payload);

            const upgrade = req.headers.get("upgrade") || "";
            if (upgrade.toLowerCase() !== "websocket") {
                return new Response("Expected websocket", { status: 426 });
            }

            const { socket, response } = Deno.upgradeWebSocket(req);

            socket.onopen = () => {
                console.log(`${payload.username} connected to protected WebSocket`);
                socket.send(`Welcome ${payload.username}!`);
            };

            socket.onmessage = (event) => {
                console.log(`${payload.username}: ${event.data}`);
                socket.send(`Authenticated message from ${payload.username}: ${event.data}`);
            };

            return response;
        } catch (error) {
            return new Response("Invalid token", { status: 401 });
        }
    }

    return new Response("WebSocket auth server running");
}

console.log("WebSocket auth server listening on http://localhost:8000");
await serve(authHandler, { port: 8000 });