tekir
All Packages
Securityv0.1.7

@tekir/cors

Configurable CORS middleware with per-origin callbacks.

Installation

$bun add @tekir/cors

Features

  • Allow all, specific, or callback-based origins
  • Configurable methods, headers, and credentials
  • Preflight OPTIONS handling with 204 response
  • Max-age for preflight caching
  • Enable/disable toggle

Quick Example

TypeScript
import { cors } from '@tekir/cors'

app.router.use(cors({
  origin: ['https://myapp.com'],
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  credentials: true,
}))

Changelog

v0.1.7LatestSeptember 16, 2026
  • Published output now uses the shared Node-targeted ESM bundle pipeline with external dependencies and generated TypeScript declarations, while Bun consumers keep the native source export.
v0.1.6July 23, 2026
  • Package metadata now follows the shared compatible 0.1.x dependency range used by this coordinated Tekir release.
v0.1.5June 13, 2026
  • CORS now requires an explicit origin allowlist when credentials are enabled. Combining credentials: true with origin: true (reflect any origin) now throws at construction; you must pass a concrete string, array, or function.
  • With credentials enabled, an Origin: null request is now passed through without CORS headers instead of echoing null, and Access-Control-Allow-Headers reflects only the headers the client actually asked for rather than * (the * behavior is kept when credentials are off).
  • Array origin matching is now exact and case-sensitive (the previous lowercasing is gone), and empty methods/headers no longer emit an empty Allow-* header.
  • Found and fixed with Fable.
v0.1.3May 3, 2026
  • When the chain throws and no inner middleware set ctx.$result along the way, the middleware no longer coerces the missing result to a 204. The previous behavior won the race against an outer error handler that returns the real error response (because the framework only adopts a returned response when ctx.$result is still undefined), so the client could see a CORS-OK 204 instead of a 401/500. Now the throw simply propagates and the outer handler builds the actual response. When an inner middleware did set ctx.$result before re-throwing, CORS headers still merge onto it as before.
v0.1.2May 3, 2026
  • Error responses now carry CORS headers regardless of middleware order. The middleware wraps await next() in a try/catch, runs the header merge whether the chain resolved or threw, and re-throws so outer error handlers and loggers still see the original error. Without this, putting cors() ahead of an error-handling middleware silently dropped Access-Control-Allow-Origin from every error response, and the browser blocked the response with a generic CORS error even though the API responded correctly.
v0.1.1May 3, 2026
  • Actual responses (not just preflight) now carry CORS headers. The middleware previously stashed Access-Control-* values on ctx.store.__corsHeaders for downstream code to apply, but nothing in tekir read them back, so browsers blocked every cross-origin POST/GET even when preflight succeeded. The middleware now injects the headers directly onto the response after the handler runs.
  • Routes that return a raw Response object (SSE streams, file downloads, custom payloads) now get CORS headers too. The middleware coerces whatever the handler returned into a Response and merges the headers in, preserving the original status, body stream, and any handler-set headers.
  • Vary: Origin is appended on every CORS-injected response so HTTP caches do not serve a response built for one origin to a request from another. When the handler already set Vary, Origin is added to the existing list instead of overwriting it.
v0.1.0April 1, 2026
  • Initial release

Other Security packages