or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

advanced-features.mdcore-framework.mderror-handling.mdevent-handling.mdhandlers-middleware.mdindex.mdrequest-processing.mdresponse-handling.mdruntime-adapters.mdweb-utilities.md
tile.json

web-utilities.mddocs/

Web Utilities

Essential web utilities including cookie management, session handling, CORS support, authentication, caching, and static file serving.

Capabilities

Cookie Management

Comprehensive cookie handling with support for chunked cookies and advanced options.

/**
 * Parse all cookies from request
 * @param event - HTTP event
 * @returns Object with all cookie key-value pairs
 */
function parseCookies(event: HTTPEvent): Record<string, string>;

/**
 * Get a single cookie value by name
 * @param event - HTTP event
 * @param name - Cookie name
 * @returns Cookie value or undefined
 */
function getCookie(event: HTTPEvent, name: string): string | undefined;

/**
 * Set a cookie in the response
 * @param event - H3 event
 * @param name - Cookie name
 * @param value - Cookie value
 * @param options - Cookie options (httpOnly, secure, etc.)
 */
function setCookie(
  event: H3Event,
  name: string,
  value: string,
  options?: CookieSerializeOptions
): void;

/**
 * Delete a cookie from the response
 * @param event - H3 event
 * @param name - Cookie name
 * @param serializeOptions - Cookie options for deletion
 */
function deleteCookie(
  event: H3Event,
  name: string,
  serializeOptions?: CookieSerializeOptions
): void;

/**
 * Get a chunked cookie (for large values)
 * @param event - HTTP event
 * @param name - Cookie name prefix
 * @returns Reassembled cookie value or undefined
 */
function getChunkedCookie(event: HTTPEvent, name: string): string | undefined;

/**
 * Set a chunked cookie (for large values)
 * @param event - H3 event
 * @param name - Cookie name prefix
 * @param value - Cookie value to chunk
 * @param options - Cookie options including chunk size
 */
function setChunkedCookie(
  event: H3Event,
  name: string,
  value: string,
  options?: CookieSerializeOptions & { chunkMaxLength?: number }
): void;

/**
 * Delete a chunked cookie
 * @param event - H3 event
 * @param name - Cookie name prefix
 * @param serializeOptions - Cookie options for deletion
 */
function deleteChunkedCookie(
  event: H3Event,
  name: string,
  serializeOptions?: CookieSerializeOptions
): void;

Usage Examples:

import { getCookie, setCookie, deleteCookie, parseCookies } from "h3";

// Basic cookie operations
const cookieHandler = defineHandler((event) => {
  // Get single cookie
  const theme = getCookie(event, "theme") || "light";
  
  // Get all cookies
  const allCookies = parseCookies(event);
  
  // Set cookie with options
  setCookie(event, "user_preference", "dark_mode", {
    httpOnly: true,
    secure: true,
    sameSite: "strict",
    maxAge: 60 * 60 * 24 * 30 // 30 days
  });
  
  return { theme, cookies: allCookies };
});

// Session cookies
const sessionHandler = defineHandler((event) => {
  const sessionId = getCookie(event, "session_id");
  
  if (!sessionId) {
    const newSessionId = generateSessionId();
    setCookie(event, "session_id", newSessionId, {
      httpOnly: true,
      secure: process.env.NODE_ENV === "production",
      sameSite: "lax",
      path: "/"
    });
    return { newSession: true, sessionId: newSessionId };
  }
  
  return { sessionId };
});

// Large cookie values
const chunkedCookieHandler = defineHandler((event) => {
  // For very large cookie values (>4KB)
  const largeData = getCookie(event, "large_data") || getChunkedCookie(event, "large_data");
  
  if (!largeData) {
    const bigValue = JSON.stringify({ data: "very large data object..." });
    setChunkedCookie(event, "large_data", bigValue, {
      chunkMaxLength: 3000, // Split into 3KB chunks
      httpOnly: true
    });
  }
  
  return { hasLargeData: !!largeData };
});

// Cookie cleanup
const logoutHandler = defineHandler((event) => {
  deleteCookie(event, "session_id");
  deleteCookie(event, "user_preferences");
  deleteChunkedCookie(event, "large_data");
  
  return { loggedOut: true };
});

Session Management

Encrypted session handling with flexible storage and configuration.

/**
 * Create a session manager for the request
 * @param event - HTTP event
 * @param config - Session configuration
 * @returns Promise resolving to session manager
 */
function useSession<T = any>(
  event: HTTPEvent,
  config: SessionConfig
): Promise<SessionManager<T>>;

/**
 * Get session data
 * @param event - HTTP event
 * @param config - Session configuration
 * @returns Promise resolving to session object
 */
function getSession<T = any>(
  event: HTTPEvent,
  config: SessionConfig
): Promise<Session<T>>;

/**
 * Update session data
 * @param event - HTTP event
 * @param config - Session configuration
 * @param update - Session update function or partial data
 * @returns Promise resolving to updated session
 */
function updateSession<T = any>(
  event: HTTPEvent,
  config: SessionConfig,
  update?: SessionUpdate<T>
): Promise<Session<T>>;

/**
 * Encrypt and seal session data
 * @param event - HTTP event
 * @param config - Session configuration
 * @returns Promise resolving to encrypted session string
 */
function sealSession<T = any>(
  event: HTTPEvent,
  config: SessionConfig
): Promise<string>;

/**
 * Decrypt and unseal session data
 * @param event - HTTP event
 * @param config - Session configuration
 * @param sealed - Encrypted session string
 * @returns Promise resolving to decrypted session data
 */
function unsealSession(
  event: HTTPEvent,
  config: SessionConfig,
  sealed: string
): Promise<Partial<Session>>;

/**
 * Clear session data
 * @param event - HTTP event
 * @param config - Partial session configuration
 * @returns Promise resolving when session is cleared
 */
function clearSession(
  event: HTTPEvent,
  config: Partial<SessionConfig>
): Promise<void>;

Usage Examples:

import { useSession, getSession, updateSession, clearSession } from "h3";

// Session configuration
const sessionConfig = {
  name: "h3-session",
  password: process.env.SESSION_SECRET, // 32+ character secret
  httpOnly: true,
  secure: process.env.NODE_ENV === "production",
  maxAge: 60 * 60 * 24 * 7 // 7 days
};

// Basic session usage
const sessionHandler = defineHandler(async (event) => {
  const session = await getSession(event, sessionConfig);
  
  // Access session data
  const userId = session.data?.userId;
  const visits = (session.data?.visits || 0) + 1;
  
  // Update session
  await updateSession(event, sessionConfig, {
    userId: userId || "anonymous",
    visits,
    lastVisit: Date.now()
  });
  
  return { userId, visits };
});

// Login handler
const loginHandler = defineHandler(async (event) => {
  const { username, password } = await readBody(event);
  
  const user = await authenticateUser(username, password);
  if (!user) {
    throw HTTPError.status(401, "Invalid credentials");
  }
  
  // Create session
  await updateSession(event, sessionConfig, {
    userId: user.id,
    username: user.username,
    roles: user.roles,
    loginTime: Date.now()
  });
  
  return { user: { id: user.id, username: user.username } };
});

// Session manager usage
const advancedSessionHandler = defineHandler(async (event) => {
  const sessionManager = await useSession(event, sessionConfig);
  
  // Check if session exists
  if (!sessionManager.data) {
    await sessionManager.update({ 
      created: Date.now(),
      visits: 1 
    });
  } else {
    await sessionManager.update(data => ({
      ...data,
      visits: (data.visits || 0) + 1,
      lastVisit: Date.now()
    }));
  }
  
  return { session: sessionManager.data };
});

// Logout handler
const logoutHandler = defineHandler(async (event) => {
  await clearSession(event, sessionConfig);
  return { loggedOut: true };
});

// Session with custom storage
const customSessionConfig = {
  ...sessionConfig,
  async serialize(data) {
    // Custom serialization
    return JSON.stringify(data);
  },
  async deserialize(str) {
    // Custom deserialization
    return JSON.parse(str);
  }
};

CORS Support

Cross-Origin Resource Sharing (CORS) handling with flexible configuration.

/**
 * Check if request is a CORS preflight request
 * @param event - HTTP event
 * @returns True if request is preflight
 */
function isPreflightRequest(event: HTTPEvent): boolean;

/**
 * Append CORS preflight headers to response
 * @param event - H3 event
 * @param options - CORS configuration options
 */
function appendCorsPreflightHeaders(event: H3Event, options: CorsOptions): void;

/**
 * Append CORS headers to response
 * @param event - H3 event
 * @param options - CORS configuration options
 */
function appendCorsHeaders(event: H3Event, options: CorsOptions): void;

/**
 * Handle CORS request with full processing
 * @param event - H3 event
 * @param options - CORS configuration options
 * @returns False if not CORS, Response for preflight
 */
function handleCors(event: H3Event, options: CorsOptions): false | Response;

/**
 * Check if origin is allowed by CORS configuration
 * @param origin - Origin to check
 * @param options - CORS configuration options
 * @returns True if origin is allowed
 */
function isCorsOriginAllowed(origin: string, options: CorsOptions): boolean;

Usage Examples:

import { handleCors, appendCorsHeaders, isPreflightRequest } from "h3";

// Basic CORS handling
const corsHandler = defineHandler((event) => {
  const corsResponse = handleCors(event, {
    origin: true, // Allow all origins
    methods: ["GET", "POST", "PUT", "DELETE"],
    allowedHeaders: ["Content-Type", "Authorization"],
    credentials: true
  });
  
  if (corsResponse) {
    return corsResponse; // Preflight response
  }
  
  return { message: "CORS enabled" };
});

// Selective CORS
const selectiveCorsHandler = defineHandler((event) => {
  const corsOptions = {
    origin: (origin) => {
      const allowedOrigins = [
        "https://myapp.com",
        "https://admin.myapp.com"
      ];
      return allowedOrigins.includes(origin) || origin.endsWith(".myapp.com");
    },
    methods: ["GET", "POST"],
    allowedHeaders: ["Content-Type", "X-API-Key"],
    exposedHeaders: ["X-Total-Count"],
    maxAge: 86400 // 24 hours
  };
  
  const corsResponse = handleCors(event, corsOptions);
  if (corsResponse) return corsResponse;
  
  return { data: "API response" };
});

// Manual CORS handling
const manualCorsHandler = defineHandler((event) => {
  if (isPreflightRequest(event)) {
    appendCorsPreflightHeaders(event, {
      origin: "https://trusted-app.com",
      methods: ["GET", "POST", "OPTIONS"],
      allowedHeaders: ["Content-Type"]
    });
    return new Response(null, { status: 204 });
  }
  
  appendCorsHeaders(event, {
    origin: "https://trusted-app.com",
    credentials: true
  });
  
  return { message: "Manual CORS" };
});

// Environment-based CORS
const envCorsHandler = defineHandler((event) => {
  const isDevelopment = process.env.NODE_ENV === "development";
  
  const corsOptions = {
    origin: isDevelopment ? true : ["https://production-app.com"],
    methods: ["GET", "POST", "PUT", "DELETE"],
    allowedHeaders: ["Content-Type", "Authorization"],
    credentials: !isDevelopment
  };
  
  const corsResponse = handleCors(event, corsOptions);
  if (corsResponse) return corsResponse;
  
  return { environment: process.env.NODE_ENV };
});

Authentication

Basic authentication utilities and middleware.

/**
 * Require basic authentication for request
 * @param event - HTTP event
 * @param opts - Basic auth options
 * @returns Promise resolving to true if authenticated
 * @throws HTTPError if not authenticated
 */
function requireBasicAuth(
  event: HTTPEvent,
  opts: BasicAuthOptions
): Promise<true>;

/**
 * Create basic authentication middleware
 * @param opts - Basic auth options
 * @returns Middleware function
 */
function basicAuth(opts: BasicAuthOptions): Middleware;

Usage Examples:

import { basicAuth, requireBasicAuth } from "h3";

// Basic auth middleware
const authMiddleware = basicAuth({
  realm: "Admin Area",
  users: {
    admin: "secret123",
    user: "password456"
  }
});

// Apply to routes
app.use("/admin", authMiddleware);

// Custom authentication
const customAuthHandler = defineHandler(async (event) => {
  await requireBasicAuth(event, {
    realm: "API Access",
    async verify(username, password) {
      const user = await database.users.findOne({ username });
      return user && await bcrypt.compare(password, user.passwordHash);
    }
  });
  
  return { message: "Authenticated successfully" };
});

// Environment-based auth
const secureHandler = defineHandler(async (event) => {
  if (process.env.NODE_ENV === "production") {
    await requireBasicAuth(event, {
      realm: "Production API",
      users: {
        [process.env.API_USERNAME]: process.env.API_PASSWORD
      }
    });
  }
  
  return { data: "secure data" };
});

Caching

HTTP caching utilities for cache control headers.

/**
 * Handle cache headers based on conditions
 * @param event - H3 event
 * @param opts - Cache conditions and options
 * @returns True if response should be served from cache
 */
function handleCacheHeaders(event: H3Event, opts: CacheConditions): boolean;

Usage Examples:

import { handleCacheHeaders } from "h3";

// Basic caching
const cachedHandler = defineHandler((event) => {
  const isCached = handleCacheHeaders(event, {
    maxAge: 3600, // 1 hour
    etag: "resource-version-123",
    lastModified: new Date("2023-01-01")
  });
  
  if (isCached) {
    return new Response(null, { status: 304 }); // Not Modified
  }
  
  return { data: "fresh data", timestamp: Date.now() };
});

// Conditional caching
const conditionalCacheHandler = defineHandler((event) => {
  const resource = getResource();
  
  const isCached = handleCacheHeaders(event, {
    maxAge: resource.isPublic ? 3600 : 0,
    etag: resource.etag,
    lastModified: resource.updatedAt,
    staleWhileRevalidate: 60,
    mustRevalidate: !resource.isPublic
  });
  
  if (isCached) {
    return new Response(null, { status: 304 });
  }
  
  return resource;
});

Type Definitions

Cookie Types

/**
 * Cookie serialization options
 */
interface CookieSerializeOptions {
  /**
   * Cookie domain
   */
  domain?: string;
  
  /**
   * Cookie expiration date
   */
  expires?: Date;
  
  /**
   * HTTP only flag
   */
  httpOnly?: boolean;
  
  /**
   * Max age in seconds
   */
  maxAge?: number;
  
  /**
   * Cookie path
   */
  path?: string;
  
  /**
   * Same site policy
   */
  sameSite?: "strict" | "lax" | "none" | boolean;
  
  /**
   * Secure flag
   */
  secure?: boolean;
}

Session Types

/**
 * Session configuration
 */
interface SessionConfig {
  /**
   * Session cookie name
   */
  name?: string;
  
  /**
   * Encryption password (32+ characters)
   */
  password: string;
  
  /**
   * Cookie options
   */
  httpOnly?: boolean;
  secure?: boolean;
  sameSite?: "strict" | "lax" | "none";
  maxAge?: number;
  domain?: string;
  path?: string;
}

/**
 * Session data interface
 */
interface Session<T = any> {
  data?: T;
}

/**
 * Session manager interface
 */
interface SessionManager<T = any> {
  data?: T;
  update(data: T | ((current: T) => T)): Promise<void>;
  clear(): Promise<void>;
}

/**
 * Session update type
 */
type SessionUpdate<T> = T | ((current: T) => T);

CORS Types

/**
 * CORS configuration options
 */
interface CorsOptions {
  /**
   * Allowed origins
   */
  origin?: boolean | string | string[] | ((origin: string) => boolean);
  
  /**
   * Allowed HTTP methods
   */
  methods?: string[];
  
  /**
   * Allowed headers
   */
  allowedHeaders?: string[];
  
  /**
   * Exposed headers
   */
  exposedHeaders?: string[];
  
  /**
   * Allow credentials
   */
  credentials?: boolean;
  
  /**
   * Preflight max age
   */
  maxAge?: number;
}

Authentication Types

/**
 * Basic authentication options
 */
interface BasicAuthOptions {
  /**
   * Authentication realm
   */
  realm?: string;
  
  /**
   * Static user credentials
   */
  users?: Record<string, string>;
  
  /**
   * Custom verification function
   */
  verify?: (username: string, password: string) => boolean | Promise<boolean>;
}

Caching Types

/**
 * Cache conditions for HTTP caching
 */
interface CacheConditions {
  /**
   * Max age in seconds
   */
  maxAge?: number;
  
  /**
   * ETag for conditional requests
   */
  etag?: string;
  
  /**
   * Last modified date
   */
  lastModified?: Date;
  
  /**
   * Stale while revalidate in seconds
   */
  staleWhileRevalidate?: number;
  
  /**
   * Must revalidate flag
   */
  mustRevalidate?: boolean;
  
  /**
   * No cache flag
   */
  noCache?: boolean;
  
  /**
   * No store flag
   */
  noStore?: boolean;
}