npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@weapon/gateway

v1.0.4

Published

Server-side HTTP host [weapon](https://github.com/sigitex/weapon).

Downloads

305

Readme

@weapon/gateway

Server-side HTTP host weapon.

🚧 Experimental

Note: This package currently exports TypeScript sources directly. A TypeScript-compatible runtime or bundler (Bun, etc.) is required.

Takes a spec, resolves authentication, matches routes, runs the executor, and returns HTTP responses. Built on the standard Request/Response API.

Installation

bun add @weapon/gateway

API

gateway(spec, transport, config, services)

Creates an executor and HTTP host in one call. This is the primary entry point for most server setups.

import { gateway } from "@weapon/gateway"

const api = gateway(
  Spec,
  Spec.transports.http,
  {
    authenticate: async (token) => verifyJwt(token),
    authorize: {
      onRequest(config, container) {
        if (config.user && !container.resolve("identity")) {
          throw new Error("Unauthorized")
        }
      },
    },
  },
  [TaskService, UserService],
)

Bun.serve({ fetch: api.fetch })

Parameters:

| Name | Type | Description | |---|---|---| | spec | Spec<Protocol> | The spec instance | | transport | TransportConfig<Config, HttpOperationConfig> | The HTTP transport from Spec.transports.http | | config | GatewayConfig<Protocol, Config> | Auth resolver + middleware implementations | | services | BoundService[] | Array of bound services |

Returns: { executor: Executor, fetch: (request: Request) => Promise<Response> }

The fetch function is a standard Request -> Response handler compatible with Bun, Cloudflare Workers, Deno, and any framework that accepts the Fetch API signature.

httpHost(transport, executor, config)

Lower-level API. Creates just the HTTP host, given an executor you've already built. Use this when you need direct control over executor creation.

import { executor } from "@weapon/spec"
import { httpHost } from "@weapon/gateway"

const exec = executor(Spec, { middleware: { authorize: myAuthMiddleware }, services })

const host = httpHost(Spec.transports.http, exec, {
  authenticate: async (token) => verifyJwt(token),
})

Bun.serve({ fetch: host.fetch })

Parameters:

| Name | Type | Description | |---|---|---| | transport | TransportConfig<Config, HttpOperationConfig> | The HTTP transport (carries auth type info) | | executor | Executor | A pre-built executor | | config | HttpHostConfig<Config> | Auth resolver and optional base container |

Returns: { fetch(request: Request, inherited?: Container): Promise<Response> }

Config

GatewayConfig<Protocol, Config>

A flat config merging the HTTP host config and all middleware implementations:

{
  // Required: auth resolver matching the declared scheme
  authenticate: (credentials) => identity | undefined,

  // Optional: base DI container
  container: myContainer,

  // One key per middleware declared in the spec
  authorize: { onRequest(config, container) { ... } },
  rateLimit: { onRequest(config, container) { ... } },
}

HttpHostConfig<Config>

| Field | Type | Description | |---|---|---| | authenticate | AuthResolverFor<AuthFromConfig<Config>> | Auth resolver (signature derived from auth scheme) | | container | Container? | Optional base DI container (cloned per request) |

Route Matching

The HTTP host matches requests by method and path. Path parameters use {param} syntax in operation definitions and are extracted automatically:

// Definition
{ http: "GET /users/{id}", input: type({ id: "string" }), ... }

// Request: GET /users/abc
// → input: { id: "abc" }

Route matching uses regexparam. Operations without http config are skipped.

Request Lifecycle

  1. Match — find the operation whose method + path matches the request
  2. Container — clone the base container (or create a new one)
  3. Authenticate — extract credentials from the request and call the resolver; bind the resolved identity into the container
  4. Parse input — for GET/HEAD/OPTIONS: query params + path params; for others: JSON body + path params
  5. Execute — call executor.handle() (validates input, runs middleware, calls handler)
  6. Respond — serialize the output:
    • Response instance returned as-is
    • undefined returns 204 No Content
    • Anything else returns 200 with application/json
    • No match returns 404

Auth Resolution

The resolver signature is derived from the auth scheme declared in the spec:

| Scheme | Resolver signature | |---|---| | http.authenticate.basic<I>() | (username: string, password: string) => I \| undefined | | http.authenticate.bearer<I>() | (token: string) => I \| undefined | | http.authenticate.cookie<I>(name) | (value: string) => I \| undefined | | http.authenticate.header<I>(name) | (value: string) => I \| undefined | | http.authenticate.query<I>(name) | (value: string) => I \| undefined |

All resolvers may return a Promise. Return undefined to indicate auth failure (the identity simply won't be bound).

When multiple auth schemes are declared (as an array), they are tried in order; the first to return a non-undefined identity wins.

Types

| Type | Description | |---|---| | GatewayConfig<Protocol, Config> | Flat config — auth resolver + middleware implementations | | HttpHostConfig<Config> | Auth resolver + optional container | | AuthResolverFor<Auth> | Maps an auth scheme type to its resolver function signature | | AuthFromConfig<Config> | Extracts auth scheme type(s) from HttpConfig, unwrapping arrays |

License

MIT