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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@clearc2/headlamp

v2.5.1

Published

Express API documenter

Downloads

32

Readme

@clearc2/headlamp

Generate express api documentation automagically.

Requirements

This issues grep commands to search code. If you would like to use the source code searching feature, your system must have grep installed.

Install

yarn add -D @clearc2/headlamp

Create a new routes directory.

server/
  routes/
  server.js

In your express api bootstrap file:

// server/server.js

import express from 'express'
import bodyParser from 'body-parser'
import path from 'path'
import fs from 'fs'
import cors from 'cors'
import shine from '@clearc2/headlamp'

const app = express()
app.use(cors())
app.use(bodyParser.json())

// old routes here

shine(app, {
  title: 'IOP API Docs',
  description: String(fs.readFileSync(path.resolve(__dirname, '..', 'readme.md'))),
  routes: path.resolve(__dirname, 'routes'),
  src: path.resolve(__dirname, '..', 'src'),
  srcDir: '_headlamp',
  server: [
    path.resolve(__dirname),
    path.resolve(__dirname, '..', 'src', 'redux', 'server')
  ],
  hidePath: path.resolve(__dirname, '..'),
  headers: {
      Authorization: {
          value: 'foobar',
          help: 'jwt auth token'
      },
      'X-Custom-Thing': 'abc'
  },
  responses: [
    {
      title: 'Invalid request',
      status: 400,
      response: {
        errors: [
          {error: 'Invalid request'}
        ]
      }
    },
    {
      title: 'Server error',
      status: 500,
      response: {
        errors: [
          {error: 'Something went wrong.'}
        ]
      }
    }
  ]
})

const PORT = process.env.PORT || 5033
app.listen(PORT, () => {
  console.log('Dev Express server running at localhost:' + PORT)
})

After starting your mock server, you will have an api explorer at http://localhost:<port>/_docs.

Configuration

The second argument to the shine function is a configuration object. All are optional.

title

Turns into the header of the api explorer.

description

General api description/documentation. Supports markdown.

routes

The directory to the route files. See route file documentation below.

src

The source code path. Can be a single path or array of paths.

srcDir

The name of directories within your src where route files are located.

server

The mock server path. Can be a single path or array of paths.

hidePath

Removes the path from the file names in the api explorer.

headers

Headers to send for every request. See params documentation below for similar formatting.

responses

Default responses that will be associated with every file route. Useful for documenting error responses. Should be an array of response objects. These will only be applied to routes defined via route files. See the responses documentation below.

Route files

This package gives you a new way to define mock endpoints through route files. Route files can be nested in the routes directory. Example:

server/
  routes/
    auth-info.js
    companies/
      get-companies.js
      save-company.js
  server.js

The files will automatically get incorporated into the mock server as functional endpoints.

Structure

Route files can either be a .js file that exports an object or a .json file. See this example route file.

// server/routes/companies/employees.js

export default {
  path: '/companies/:companyUnid/employees',
  methods: ['GET'],
  title: 'Company employees',
  description: 'Fetches all active employees',
  response: {
    employees: [
      {
        name: 'John Doe'
      },
      {
        name: 'Bob Smith'
      }
    ]
  }
}

The equivalent json file of the above would look like below and behave identically.

{
  "path": "/companies/:companyUnid/employees",
  "methods": ["GET"],
  "title": "Company employees",
  "description": "Fetches all active employees",
  "response": {
    "employees": [
      {
        "name": "John Doe"
      },
      {
        "name": "Bob Smith"
      }
    ]
  }
}

path

This must be a valid express route path.

method

A single http verb that this endpoint responds to. Ex. POST

methods

Routes can respond to multiple http methods. This must be an array of http verbs that this endpoint responds to. Ex. ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']

title

Only used for documentation in the api explorer ui.

description

Only used for documentation in the api explorer ui. Supports markdown.

params

URL params are the tokens prefixed by : in the path. These params can be further defined:

export default {
  path: '/companies/:companyUnid/employees',
  params: {
    companyUnid: 'abcdef'
  }
  // ...
}

The above will prepopulate this param's input in the api explorer. You can provide additional help text by using an object.

export default {
  path: '/companies/:companyUnid/employees',
  params: {
    companyUnid: {
      value: 'abcdef',
      help: 'Company Unid'
    }
  }
  // ...
}

The help text will show up directly beneath the param's input in the api explorer.

query

Query params can be defined in the same way.

export default {
  path: '/companies/:companyUnid/employees',
  query: {
    hiredAfter: {
      value: '01-01-2018',
      help: 'Format MM-DD-YYYY'
    }
  }
  // ...
}

headers

Headers to send with this request. Same format as params and query.

payload

POST, PUT, and PATCH methods allow for example payloads. These payloads will populate the payload input in the api explorer.

export default {
  path: '/contact',
  methods: ['POST'],
  payload: {
    contact: {
      firstName: 'John',
      lastName: 'Doe'
    }
  }
  // ...
}

In the case of endpoints accepting both POST and PUT requests, you can define unique payloads for both.

export default {
  path: '/contact',
  methods: ['POST', 'PUT'],
  payload: {
    POST: {
      contact: {
        firstName: 'John',
        lastName: 'Doe'
      }
    },
    PUT: {
      contact: {
        id: 'abcded',
        firstName: 'John',
        lastName: 'Doe'
      }
    }
  }
  // ...
}

response

Responses can be simple javascript objects...

export default {
  path: '/people',
  methods: ['GET'],
  response: {
    people: {
      [
        {name: 'John Doe'},
        {name: 'Bob Smith'}
      ]
    }
  }
}

Or come from fixture files...

export default {
  path: '/people',
  methods: ['GET'],
  response: require('./_people.json')
}

Or dynamically generated based on the request...

export default {
  path: '/people',
  methods: ['GET', 'POST', 'PUT'],
  response: (req, res) => {
    if (req.method === 'POST') {
      return res.status(400).json({
        errors: [
          {detail: 'Something went wrong :('}
        ]
      })
    }

    if (req.method === 'PUT') {
      return res.status(500).json({
        errors: [
          {detail: 'CRITICAL FAILURE'}
        ]
      })
    }

    return res.status(200).json(require('./_people.json'))
  }
}

Unless a function is provided, a 200 status code will be sent.

responses

Instead of, or in conjunction with, the response key, you can provide static responses.

export default {
  path: '/people',
  method: 'POST',
  responses: [
    {
      title: 'All good',
      description: 'Some **markdown** describing this response',
      status: 200,
      response: {
        foo: 'bar'
      }
    },
    () => ({
      title: 'Unauthorized',
      status: 401,
      response: require('./_bigData') // large fixture that doesn't need to be loaded into memory right away
    }),
    {
      title: 'No bueno',
      status: 500,
      response: {
        errors: [
          {error: 'Something went wrong :('}
        ]
      }
    }
  ]
}

These responses will be displayed in the api explorer. Because of that, they do not have access to the express req or res objects. Zero arguments are passed to functional responses. If you need to add a delay or dynamically generate a response based on the request, use response.

globalHeaders

Boolean to determine whether to merge the globally defined headers to this route. Defaults true.

globalResponses

Boolean to determine whether to concat the globally defined responses to this route. Defaults true.

Response objects

Static responses must either be an object or a function that returns an object. Static response objects have the following fields:

title

The title of the static response.

description

The description of the static response. Supports markdown.

status

The status http status code.

response

The response payload.

Response resolution

The following priority is used to determine which response to use.

  • If activated response, use it
  • If response object/function exists, use it
  • If first response in responses exists, use it
  • Sends error response

Fixtures

Fixture files can be nested in the routes directory but their file names must be prefixed with an underscore to not be interpreted as a route file.

server/
  routes/
    people/
      get-people/
        _people.json     # will not be interpreted as a route file
        route.js         # will be interpreted as a route file
      save-person.js     # will be interpreted as a route file
      update-person.json # will be interpreted as a route file

Explorer features

Search

Searching in the frontend is case-insensitive. You can omit path variables and simply provide a colon. Ex.

/companies/:/employees/:/address

The above would match:

/companies/:companyUnid/employees/:unid/address