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 🙏

© 2025 – Pkg Stats / Ryan Hefner

autodisco

v0.4.3

Published

Automatically generate OpenAPI schemas by probing RESTful APIs

Readme

🪩 AutoDisco

Github Actions NPM version NPM last update License

AutoDisco is a tool for automatic discovery of REST APIs that do not provide an OpenAPI specification themselves. It generates an OpenAPI schema by inferring request and response structures from user-defined probes.

Installation

npm install autodisco

Usage

import discover from 'autodisco'

await discover({
  baseUrl: 'https://jsonplaceholder.typicode.com',

  probes: {
    get: {
      '/todos': {},
      '/posts': {},

      '/posts/{id}': {
        params: {
          id: 1,
        },
      },

      '/users/{id}': {
        params: {
          id: 1,
        },
      },

      '/comments': {
        query: {
          postId: 1,
        },
      },
    },

    post: {
      '/users': {
        body: {
          name: 'John Doe',
          username: 'johndoe',
          email: '[email protected]',
        },
      },
    },
  },
})

This will create an OpenAPI schema in autodisco/openapi/schema.json.

CLI Usage

You can also use AutoDisco via the command line interface (CLI). First, create a configuration file, e.g. autodisco.config.{js,ts,mjs,cjs}:

export default {
  baseUrl: 'https://jsonplaceholder.typicode.com',

  probes: {
    get: {
      '/todos': {},
      '/posts': {},
    },
  },
}

Then run the autodisco command in your terminal:

npx autodisco

This will create an OpenAPI schema in autodisco/openapi/schema.json.

Generating TypeScript Types

If you also want to generate TypeScript types for the probed endpoints, you can enable the typescript option in the generate configuration:

import discover from 'autodisco'

await discover({
  baseUrl: 'https://jsonplaceholder.typicode.com',

  probes: {
    get: { '/todos': {} },
  },

  generate: {
    typescript: true,
  },
})

This will create TypeScript types in the autodisco/typescript directory in addition to the OpenAPI schema:

autodisco/
├── openapi/
│   └── schema.json
└── typescript/
    └── types.d.ts

[!NOTE] Make sure to install openapi-typescript if you want to use TypeScript type generation: npm install openapi-typescript

Generating Zod Schemas

If you also want to generate Zod schemas for the probed endpoints, you can enable the zod option in the generate configuration:

import discover from 'autodisco'

await discover({
  baseUrl: 'https://jsonplaceholder.typicode.com',

  probes: {
    get: {
      '/todos': {},
    },

    post: {
      '/users': {
        body: {
          name: 'John Doe',
          username: 'johndoe',
          email: '[email protected]',
        },
      },
    },
  },

  generate: {
    zod: true,
  },
})

This will create Zod schemas in the autodisco/zod directory in addition to the OpenAPI schema:

autodisco/
├── openapi/
│   └── schema.json
└── zod/
    ├── get/
    │   └── Todos.ts
    └── post/
        └── Users.ts

[!NOTE] Make sure to install quicktype-core if you want to use Zod schema generation: npm install quicktype-core

Configuration

The discover function accepts a configuration object with the following values:

  • baseUrl: The base URL for the API (string, optional).
  • outputDir: The directory to output the generated files (string, default: autodisco).
  • probes: An object containing endpoints to probe (ProbeConfig, required).
  • headers: An object containing headers to include in all requests (Record<string, string>, optional).
  • minify: Whether to minify the generated OpenAPI schema (boolean, default: false).
  • clear: Whether to clear the output directory before generating files (boolean, default: true).
  • generate: Options to customize code generation (optional)
    • zod: Whether to generate Zod schemas (boolean | generateZodOptions, optional).
    • typescript: Whether to generate TypeScript types (boolean | generateTypescriptOptions, optional).
  • hooks: Hooks to customize the discovery process (optional).
  • logger: Custom configuration for the logger (Consola options, optional).

Probe configuration

Each probe can call an endpoint in multiple ways by specifying different combinations of params, query, and body. Probes supports the following options:

  • params: An object containing path parameters (optional).
  • query: An object containing query parameters (optional).
  • body: An object containing the request body (for POST, PUT, PATCH requests, optional).
  • headers: An object containing headers to include in the request (optional, overrides default headers).

Discovery

The discovery process involves sending HTTP requests to the specified endpoints using the provided probes. The responses are analyzed to infer the structure of the API, which is then used to generate an OpenAPI schema. If enabled, TypeScript types and Zod schemas are also generated based on the inferred structures.

When all probes are completed, their responses will be converted to Zod schemas at runtime to ensure an accurate representation of the data structures and to circumvent any serialization issues. After that, the OpenAPI schema will be generated using the inferred runtime schemas with zod-openapi in the ${outputDir}/openapi directory.

If TypeScript type generation is enabled, the OpenAPI schema will be converted to TypeScript types using openapi-typescript in the ${outputDir}/typescript directory.

If Zod schema generation is enabled, additional Zod schemas will be generated as files using quicktype in the ${outputDir}/zod directory.

Schema Inference

The schema inference process breaks a response down by first identifying the primitive data types (string, number, boolean, null) and then combining them into more complex structures such as arrays and objects.

Arrays are inferred by examining the elements within the array and determining a common schema that encompasses all elements. If the elements have varying structures, all possible schemas are searched for a common discriminator, such as a shared property name with different values. If a common discriminator is found and the number of unique schemas matches the number of available discriminators, the array will be typed as a discriminated union. When no common structure can be found, the array is inferred to contain a single object with optional properties representing all possible fields.

Objects are inferred by analyzing each property and determining its type based on the values present in the responses. If a property is missing in some responses, it is marked as optional.

Examples

Given the following responses from probing an endpoint:

{
  "users": [
    { "id": 1, "name": "Alice", "role": "admin", "extra": "data" },
    { "id": 2, "name": "Bob", "role": "user" },
    { "id": 3, "name": "Charlie", "role": "guest" }
  ]
}

The inferred schema would be:

type Response = {
  id: number
  name: string
  role: string
  extra: string | undefined
}[]

If the responses were more varied and provide a unique key for each unique kind of schema, the inference will detect it as a discriminated union such as:

{
  "users": [
    { "id": 1, "name": "Alice", "role": "admin" },
    { "id": 2, "name": "Bob", "role": "editor", "permissions": ["read", "write"] },
    { "id": 3, "name": "Charlie", "role": "guest", "extra": "data" }
  ]
}

With the inferred schema being:

type Response = ({
  id: number
  name: string
  role: 'admin'
} | {
  id: number
  name: string
  role: 'editor'
  permissions: string[]
} | {
  id: number
  name: string
  role: 'guest'
  extra: string
})[]

Hooks Reference

The hooks configuration allows you to customize the discovery process by providing functions that are called at specific points during execution.

| Hook Name | Props | Description | |-------------------------|--------------------------------------------------|-------------------------------------------------------| | discovery:start | config | Called when the discovery process begins | | probe:request | method, path, config | Called before each API probe request is made | | probe:response | method, path, config, response | Called after each API probe response is received | | probes:completed | config, results | Called when all API probing is complete | | zod:generate | method, name, inputData, rendererOptions | Called before generating Zod schemas using quicktype | | zod:generated | config | Called after Zod schema files have been generated | | zod:runtime:generate | method, path, config, sample | Called before generating runtime Zod schemas | | zod:runtime:generated | config, results | Called after runtime Zod schemas have been generated | | openapi:generate | config, components, paths | Called before generating the OpenAPI schema | | openapi:generated | config, result | Called after the OpenAPI schema has been generated | | typescript:generate | config, openapiTSOptions | Called before generating TypeScript types | | typescript:generated | config, result | Called after TypeScript types have been generated | | discovery:completed | config, totalTime, totalProbingTime | Called when the entire discovery process is completed |

Acknowledgements

This project is heavily inspired by and built with the following libraries:

📜 License

Published under the MIT License.