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

@sonatel-os/openapi-runtime

v0.2.1

Published

Enterprise-grade, zero-codegen OpenAPI runtime. Load specs dynamically, execute APIs with type-safe validation, mock responses, and robust authentication.

Downloads

22

Readme

🔥 @sonatel-os/openapi-runtime

"We deleted your SDK. You're welcome." 💅

npm version npm downloads License: MIT TypeScript Zero Codegen

The enterprise-grade, zero-codegen OpenAPI runtime.

Load specs dynamically. Execute APIs instantly. Sleep peacefully. 😴

- Before: 47 generated files, 12,000 lines, 3 merge conflicts, 1 existential crisis 😭
+ After:  1 import, 2 lines, 0 problems, mass enlightenment 🧘

Get Started · Features · Auth Magic · API Reference


😤 The Problem

Every time your backend updates their Swagger spec:

1. Run openapi-generator         ⏳ (2 minutes of your life)
2. Watch 50 files regenerate     😰 (existential dread intensifies)
3. Resolve merge conflicts       🔥 (45 minutes + therapy needed)
4. Realize half the types broke  😱 (scream internally)
5. Repeat next sprint            💀 (question career choices)

😎 The Solution

await runtime.executeAPI({ name: 'users', api: 'getUser', params: { id: 42 } })
// That's it. That's the tweet. 🐦

Zero generation. Zero maintenance. Zero drama. 💆


📦 Installation

npm install @sonatel-os/openapi-runtime
yarn add @sonatel-os/openapi-runtime
pnpm add @sonatel-os/openapi-runtime

Requirements: Node.js 18+ (we're not savages) 🦖


🚀 Quick Start

Step 1: Load Your Spec 📄

import * as runtime from '@sonatel-os/openapi-runtime'

// From a file
await runtime.save({
  name: 'products',
  specName: 'products.openapi.json'
})

// Or pass the spec directly (for the rebels 😈)
await runtime.save({
  name: 'products',
  specName: myOpenAPISpecObject
})

Step 2: Call APIs Like a Boss 😎

// GET /products/{id}
const product = await runtime.executeAPI({
  name: 'products',
  api: 'getProductById',    // Uses operationId from your spec
  params: { id: 123 },      // Path + query params
  headers: { 'X-Mood': 'happy' }
})

console.log(product.body)   // Your data, served fresh 🍽️

Step 3: There Is No Step 3 🎉

You're done. Go grab a coffee. You've earned it. ☕


⚡ Features That Slap

| Feature | What It Does | Vibe | |---------|--------------|------| | 🗂️ Multi-Spec Registry | Load products, users, payments... all at once | Juggler mode 🤹 | | 🔮 Auto-Auth Magic | Detects env vars, applies tokens automatically | Mind reader | | ✅ Request Validation | Validate payloads before sending | Preventive care 🏥 | | 🔍 Response Validation | Validate what comes back | Trust issues (healthy) | | 🎭 Mock Generation | Generate fake responses from schemas | Backend not ready? No problem | | 🎣 Interceptors | Hook into request/response lifecycle | Control freak approved | | ⚛️ React Hooks | useOpenAPI() for the React gang | Hooks, but make it API | | 📝 TypeScript Ready | Full JSDoc types, auto-generated .d.ts | IntelliSense heaven 😇 |


🔐 Authentication (The Magic Part)

The runtime auto-detects your auth setup. No config? No problem. ✨

🌱 Option 1: Environment Variables (Zero Config)

Just set env vars following this pattern, and watch the magic happen:

# 🎫 Bearer Token
BEARER_PRODUCTS_BEARERAUTH=your-jwt-token

# 🔑 API Key
OAR_PRODUCTS_APIKEY=your-api-key

# 👤 Basic Auth
BASIC_USER_PRODUCTS_BASICAUTH=username
BASIC_PASS_PRODUCTS_BASICAUTH=password

# 🔒 OAuth2 Client Credentials
OAUTH_CLIENT_ID_PRODUCTS_OAUTH2=client-id
OAUTH_CLIENT_SECRET_PRODUCTS_OAUTH2=client-secret
OAUTH_TOKEN_URL_PRODUCTS_OAUTH2=https://auth.example.com/token

📐 Pattern: {TYPE}_{SPECNAME}_{SCHEMENAME}

The runtime reads your spec's securitySchemes, finds matching env vars, and configures everything. You literally do nothing. 🪄

📝 Option 2: YAML Config (More Control)

Create openapi.auth.yml in your project root:

# 🎨 openapi.auth.yml
auth:
  products:
    schemes:
      bearerAuth:
        type: http
        scheme: bearer
        tokenFromEnv: MY_SECRET_TOKEN  # 🤫

      oauth2:
        type: oauth2
        flow: client_credentials
        tokenUrl: https://auth.example.com/oauth/token
        clientIdFromEnv: OAUTH_CLIENT_ID
        clientSecretFromEnv: OAUTH_CLIENT_SECRET
        scope: "read write"
        audience: https://api.example.com

💡 Supports ${ENV_VAR} interpolation for the extra fancy folks

🎮 Option 3: Programmatic (Full Control)

import { setAuth, bearer, apiKey, basic, clientCredentials } from '@sonatel-os/openapi-runtime'

setAuth('products', {
  // 🎫 Static or dynamic tokens
  bearerAuth: bearer({
    getToken: async () => await fetchTokenFromVault()  // 🔐
  }),

  // 🔑 API Keys
  apiKeyAuth: apiKey({
    in: 'header',
    name: 'X-API-Key',
    getValue: () => process.env.API_KEY
  }),

  // 🔒 OAuth2 with automatic token refresh
  oauth2: clientCredentials({
    tokenUrl: 'https://auth.example.com/token',
    clientId: 'my-app',
    clientSecret: process.env.CLIENT_SECRET,
    scope: 'read write'
  })
})

🛡️ Security note: OAuth token URLs must use HTTPS. We're not playing games with your credentials.


📚 API Reference

🗂️ Spec Management

// ➕ Register a spec
await runtime.save({ name: 'api', specName: 'spec.json', autoAuth: true })

// 🔄 Update a spec
await runtime.update({ name: 'api', specName: 'spec-v2.json' })

// 🗑️ Remove a spec
runtime.remove({ name: 'api' })

// 📋 List all registered specs
runtime.listSpecs()  // ['products', 'users', 'payments']

// 🔍 List operations in a spec
runtime.listAPIs({ name: 'products' })
// [{ operationId: 'getProducts', method: 'get', path: '/products' }, ...]

🚀 Execution

const response = await runtime.executeAPI({
  name: 'products',
  api: 'createProduct',
  params: { category: 'electronics' },  // 📍 Path/query params
  body: { name: 'Widget', price: 9.99 }, // 📦 Request body
  headers: { 'X-Request-ID': 'abc123' }, // 📨 Extra headers
  qs: { verbose: true }                  // ❓ Query string
})

✅ Validation

// 🔍 Validate a response
const result = runtime.validateResponseData({
  name: 'products',
  api: 'getProduct',
  status: 200,
  data: responseData
})

if (!result.valid) {
  console.error('💥 Schema violations:', result.errors)
}

// 🛡️ Validate a request body BEFORE sending
const check = runtime.validateRequestData({
  name: 'products',
  api: 'createProduct',
  body: { name: 'Widget' }  // Missing required 'price'? 🤔
})

🎭 Mocking (Backend Not Ready? We Got You 💪)

// 🎲 Generate a mock response
const mockProduct = runtime.mockAPI({
  name: 'products',
  api: 'getProduct',
  status: 200
})
// { id: 123, name: 'string', price: 0, ... }

// 📝 Get sample request body
const sampleBody = runtime.showRequestSample({
  name: 'products',
  api: 'createProduct'
})

// 🔬 Inspect the raw contract
const contract = runtime.showContract({
  name: 'products',
  api: 'getProduct'
})
// { method: 'get', path: '/products/{id}', parameters: [...], responses: {...} }

🎣 Interceptors (For Control Freaks 🎛️)

runtime.setInterceptors('products', {
  request: async (req) => {
    console.log(`📡 Calling ${req.operationId}`)
    req.headers['X-Timestamp'] = Date.now()
    return req
  },

  response: async (res) => {
    console.log(`✅ Got ${res.status} from ${res.url}`)
    return res
  },

  error: (err) => {
    console.error('💥 API Error:', err)
    logToSentry(err)
    throw err
  }
})

📨 Headers

// 🌍 Global headers (all specs)
runtime.setGlobalHeaders({
  'X-Correlation-ID': generateCorrelationId()
})

// 🎯 Per-spec headers
runtime.setSpecHeaders('products', {
  'X-Tenant': 'acme-corp'
})

⚛️ React Integration

import { useOpenAPI } from '@sonatel-os/openapi-runtime/react'

function ProductList() {
  const api = useOpenAPI('products')
  const [products, setProducts] = useState([])

  useEffect(() => {
    api.executeAPI('getProducts')
      .then(res => setProducts(res.body))
  }, [])

  return <div>{/* render products 🎨 */}</div>
}

🔄 With Loading State

import { useOpenAPIWithState } from '@sonatel-os/openapi-runtime/react'

function ProductList() {
  const { api, loading, error, execute } = useOpenAPIWithState('products')
  const [products, setProducts] = useState([])

  const loadProducts = () => execute(
    () => api.executeAPI('getProducts'),
    (res) => setProducts(res.body)
  )

  if (loading) return <Spinner /> // ⏳
  if (error) return <Error message={error.message} /> // 💥

  return <div>{/* render products 🎨 */}</div>
}

🚨 Error Handling (The Grown-Up Way)

We don't just throw generic errors. We throw specific errors with attitude:

import {
  AuthenticationError,   // 🔐
  SpecNotFoundError,     // 🔍
  OperationNotFoundError, // 🎯
  ValidationError,       // ✅
  SecurityError          // 🛡️
} from '@sonatel-os/openapi-runtime'

try {
  await runtime.executeAPI({ name: 'products', api: 'getProduct', params: { id: 1 } })
} catch (err) {
  if (err instanceof AuthenticationError) {
    console.log('🔐 Auth failed:', err.failures)
    // [{ schemes: ['bearer'], error: 'token expired' }]
  }

  if (err instanceof ValidationError) {
    console.log('❌ Validation errors:', err.errors)
  }

  if (err instanceof SecurityError) {
    console.log('🚨 Security violation:', err.details.violation)
  }
}

🎁 All errors extend OpenAPIRuntimeError with code, details, and toJSON() for easy logging


▲ Next.js Integration

🖥️ Server Components (Recommended)

// app/products/page.jsx
import 'server-only'
import * as runtime from '@sonatel-os/openapi-runtime'

export default async function ProductsPage() {
  await runtime.save({ name: 'products', specName: 'products.json' })
  const { body } = await runtime.executeAPI({ name: 'products', api: 'getProducts' })

  return <ProductList products={body} />  // 🎨
}

⚡ Server Actions

// app/actions.js
'use server'
import * as runtime from '@sonatel-os/openapi-runtime'

export async function getProducts() {
  const { body } = await runtime.executeAPI({
    name: 'products',
    api: 'getProducts'
  })
  return body  // 📦
}

⚠️ Warning: Don't import the runtime directly in Client Components. Use Server Actions or API Routes instead.


🏗️ Architecture

src/
├── 📄 index.js           # Public API facade
├── 🔢 constants.js       # All magic values (none in code!)
├── 💥 errors.js          # 9 custom error types
├── 🛠️ utils.js           # DRY utilities
├── 📦 core/
│   ├── registry.js       # Spec storage (singleton)
│   └── client.js         # Swagger client factory
├── 🔐 auth/
│   ├── providers.js      # apiKey, bearer, basic, clientCredentials
│   ├── manager.js        # Auth application logic
│   └── config.js         # YAML config loader
├── ✅ validation/
│   └── validator.js      # AJV-based schema validation
├── 🎭 mocking/
│   └── sampler.js        # Sample data generation
└── ⚛️ react/
    └── useOpenAPI.js     # React hooks

Design Principles: 🎯

  • Single Responsibility per module
  • No circular dependencies
  • All magic values in constants.js
  • Custom errors for every failure mode
  • 100% JSDoc coverage

🛡️ Security

We take security seriously (and so should you):

| Measure | Implementation | |---------|----------------| | 🔒 HTTPS Enforcement | OAuth token URLs must use HTTPS | | 🚨 No Silent Failures | Auth failures throw with full context | | ✅ Input Validation | Spec names validated against safe patterns | | ⏰ Token Caching | OAuth tokens cached with 30s expiry buffer | | 🤫 No Secrets in Code | All secrets via env vars or config files |


⚡ Performance

  • 💤 Lazy Loading: Specs loaded on-demand
  • 🗄️ Schema Caching: Compiled validators cached per-operation
  • 🎫 Token Caching: OAuth tokens cached until expiry
  • 🚫 Zero Runtime Codegen: No parsing or generation at runtime

🤝 Contributing

We welcome contributions! This project is part of the Sonatel Open Source initiative. 🧡

# 📥 Clone
git clone https://github.com/sonatel-os/openapi-runtime.git

# 📦 Install
npm install

# 🔧 Dev mode
npm run dev

# 🏗️ Build
npm run build

# 🧪 Test
npm test

Guidelines 📋

  1. 🍴 Fork the repository
  2. 🌿 Create a feature branch (git checkout -b feature/amazing-thing)
  3. 🧪 Write tests for new functionality
  4. ✅ Ensure all tests pass
  5. 🚀 Submit a PR with a clear description

🗺️ Roadmap

  • [x] 🗂️ Multi-spec registry
  • [x] 🔮 Auto-auth from env vars
  • [x] 📝 YAML config support
  • [x] ✅ Request/response validation
  • [x] 🎭 Mock generation
  • [x] ⚛️ React hooks
  • [x] 💥 Custom error types
  • [ ] 🔑 OpenID Connect support
  • [ ] 🔄 Retry with exponential backoff
  • [ ] 🗄️ Request caching layer
  • [ ] 🖥️ CLI for spec validation

📜 License

MIT © Sonatel Open Source


🔥 Built with mass frustration, deployed with mass relief 🔥

Stop generating. Start shipping. 🚀

Made with 🧡 by developers who mass mass mass hated regenerating SDKs