Skip to content

Assets and Body Limits

Rizky Zulkarnaen edited this page Sep 9, 2026 · 1 revision

Assets and Body Limits

Public asset serving (ADR-0018)

Source: docs/getting-started.md § Serving public assets

Opt-in, same-origin, no build step:

import { defineApp, json, route } from "lugas";

const app = defineApp({
  routes: {
    "/api/ping": { GET: route({ handler: () => json(200, { pong: true }) }) },
  },
  assets: {
    files: { "/index.html": "./public/index.html" },
    dirs: { "/assets/*": "./public/assets" },
  },
});
  • File mappings are exact literal paths; directory mounts are explicit prefixes ending in /* (no root catch-alls).
  • Platform support: assets.dirs requires Linux (openat2(RESOLVE_IN_ROOT) for symlink containment); on macOS/Windows configuring dirs fails closed at startup (LUGAS_ASSET_004). assets.files works on all platforms.
  • Served natively by Bun: MIME types, ETag/Last-Modified conditionals, range requests.
  • Methods: GET/HEAD serve; other methods reach the not-found policy (no 405 promise). Misses stay distinguishable from API 404s.
  • Ownership is validated at startup — an asset declaration overlapping an API route (or another asset) fails with LUGAS_ASSET_002; never resolved by declaration order.
  • Asset responses bypass guards, onError, and the whole request pipeline — keep protected files outside served directories.
  • Incompatible with cors (LUGAS_CORS_004): natively served values cannot carry the policy — see CORS.
  • Same-origin lane for the prebuilt browser client: map "/lugas-client.esm.js": "./node_modules/lugas/build/lugas-client.esm.js".

Body budgets (ADR-0019)

Source: docs/body-limits.md

Two layers, deliberately distinct:

  1. Server ceilingapp.serve({ maxRequestBodySize }) forwards to Bun.serve. Bun enforces it while consuming the body: a bare transport 413 (empty body) before parsing or handlers.
  2. Lugas budgets — application default defineApp({ bodyBudget }), per-route override route({ budget }); both clamped by the ceiling (effective = min(ceiling, selected)). Enforcement is bounded consumption ending in a 413 Problem Details response (BODY_BUDGET_EXCEEDED) before validation or handler execution.

Rules:

  • Budgets require a declared framework-parsed body (LUGAS_BODY_002 otherwise).
  • Above-ceiling configuration is rejected at serve() (LUGAS_BODY_003) — an override relaxes the default, never the ceiling.
  • Invalid configuration → LUGAS_BODY_001.
  • Budget-rejected handlers run zero application code; raw-stream (undeclared-body) routes are untouched by budgets.

Clone this wiki locally