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

@suss/contract-openapi

v0.34.0

Published

Turn an OpenAPI document into a suss contract and check it against the handlers and clients that implement it.

Readme

@suss/contract-openapi

Part of suss, which reads both sides of every call in a repository and reports where the two disagree.

This package builds suss BehavioralSummary[] from an OpenAPI 3.x specification. With it you can check TypeScript consumers against a published API contract, or check your own provider against a contract you publish, without extracting summaries from the provider's source code.

What this package is

@suss/contract-openapi reads an OpenAPI document and produces one BehavioralSummary per operation. Each summary has:

  • A kind: "handler" provider-side form.
  • boundaryBinding: { protocol: "http", method, path, framework: "openapi" }, which pairs with extracted handlers and clients through the checker's path normalization (:id ↔ {id}).
  • One transition per declared response status, with body shapes converted from OpenAPI Schema to suss TypeShape.
  • confidence: { source: "derived", level: "high" }, since the behavior is declared and not inferred.

suss check accepts these summaries exactly as it accepts extracted ones.

Minimal usage

import { openApiFileToSummaries } from "@suss/contract-openapi";
import fs from "node:fs";

const summaries = openApiFileToSummaries("openapi.yaml");
fs.writeFileSync("provider.json", JSON.stringify(summaries, null, 2));

Then pair it with a consumer extracted from your TS code:

suss check provider.json consumer.json

Or from code:

import { openApiToSummaries } from "@suss/contract-openapi";
import type { OpenApiSpec } from "@suss/contract-openapi";

const spec: OpenApiSpec = { openapi: "3.0.3", paths: { /* ... */ } };
const summaries = openApiToSummaries(spec);

What's covered

  • All standard HTTP methods on paths.<path>.<method>
  • Numeric status codes ("200", "404", etc.), range codes ("2XX" through "5XX"), and default
  • Response body schemas under content.<media-type>.schema (the JSON one when the operation offers it, otherwise the media types in sorted order)
  • Path, query, header, and cookie parameters mapped to Input.role
  • Request body schemas mapped to a single requestBody input
  • $ref to #/components/schemas/<Name> with cycle protection (recursive schemas resolve to a { type: "ref", name } placeholder)
  • Schema features: object/array/string/integer/number/boolean, enum, oneOf/anyOf, allOf (object merge), nullable, additionalProperties (as dictionary)

Range codes and default

A document can declare a response as "4XX" instead of one code. That entry means the operation can return some status between 400 and 499, without saying which. The reader keeps that meaning in two places. The entry's transition has statusCode: null, with the range under metadata.http.statusRange, and the declared contract records it under responseRanges. The checker treats a consumer branch on any status in the range (a branch on 404 against a declared 4XX) as agreeing with the contract. It asks whether the consumer covers the range at all, and does not require it to cover every status in it.

In OpenAPI, default covers every status the other entries leave out. It becomes the summary's isDefault transition and the contract's defaultResponse. The checker reads it as "the provider may return any status", so against an operation with a default, no consumer status is ever undeclared or dead. The checker does not ask the consumer to handle the default case either. That case has no concrete status to state an outcome for, and requiring a catch-all would be a rule about style, with no behavior behind it.

Limitations (v0)

  • Headers, links, callbacks and webhooks sections are not modeled.
  • Security schemes do not become transitions, so there is no synthetic 401/403.
  • Multiple content types per response: one media type gives the body shape, and the reader does not record which one. So a producer and a consumer are never compared on the media type itself. #387 tracks that.
  • Polymorphism through discriminator is not modeled. The union shape is correct, but the discriminator field is not marked.
  • Spec validation is not strict. An invalid spec may produce odd summaries instead of errors.

Where it fits in suss

The package depends only on @suss/behavioral-ir, for the IR types it produces, and yaml, for parsing the spec. It does not use the language adapter or pattern packs, since it does not extract from source.

More

Coverage

coverage

License

Licensed under Apache 2.0. See LICENSE.


For the format the summaries conform to, see docs/reference/summary-format.md.