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

blot

v0.0.34

Published

The DRY documentation builder

Downloads

75

Readme

blot

:umbrella: The DRY documentation build tool

tl;dr

API Blueprint + Transclusion + Queries = Ultra-DRY Docs

  • Build tool for normalized API Blueprints and fixtures
  • Unifies documentation and common fixtures via transclusion and queries
  • Eases the maintenance of documentation, fixtures and tests

Features

  • Dynamically link and build API Blueprints from normalized files (.md, .mson, .json, etc)
  • Reference, query and embed data using a JSON-friendly syntax
  • Generate random data anywhere using the same syntax
  • Extract and export JSON fixtures from API Blueprints
  • Export API Blueprints as HTML (web-component friendly, choose what you want by querying)
  • Multi-environment project configurations with build-specific overrides
  • Supports both standardized (bunyan) and pretty logs for sane debugging

Summary

blot minimizes duplication and introduces unification between documentation, fixtures, and API test suites. It sits on top of hazy and provides an abstract API Blueprint parser and generator.

API Blueprint is an open-source specification for programmatically documenting Restful APIs in pure Markdown. The specification is highly flexible and is focused on human readability. API Blueprints are also machine readable, so they naturally support tooling. They can be used to generate mock servers, automate integration testing, allow exportation of requests to tools such as Postman or cURL, and much much more.

A limitation of API blueprints is that they are static, and there are few (if any) tools for parsing documented requests and responses for programmatic (in-code) use in your integration and unit tests. My philosophy is that you should strive for a canonical source of fixtures in which all of your tests and documentation inherit from. Hercule, a library that blot integrates, promotes normalization by allowing data to be transcluded in markdown documents. blot also supports this through hazy, and either syntax may be used as they will both be processed. The reason that hazy is also used is because it provides additional interfaces for querying JSON fixtures and generating random data.

Fixtures

hazy is a node library for lazily processing dynamic fixture data. It provides a simple syntax for interpolating pattern-matched and/or random data into your fixtures. It alleviates the need for developers to constantly come up with names, addresses, etc. for their enormous amount of test data.

The most powerful feature of hazy is that it allows developers to dynamically embed fixtures (or sub-fixtures) via JsonPath patterns or by a simple string. This is very useful when creating and maintaining fixtures that share identical or related pieces of data, keeping your fixture data DRY as an application grows.

In blot, hazy acts as a standardized bridge between your documentation and tests. It pushes your fixtures out of your code and into a datastore such as your file system or a database, inherently canonical sources of data. Your API Blueprints and tests can then be dynamically generated by processing the fixtures via the blot API.

Examples

The following is an API blueprint decorated with some basic hazy tokens. The ~ keyword tells hazy to replace the token with categorized random data:

### Login a user [POST]

# POST /v1/auth
+ Request (application/json)

  { "username": "|~web.email|", "password": "|~text.word|" }

+ Response 200 (application/json)

  { "token": "|~misc.guid|", "refresh_token": "|~misc.guid|", "expires": "|~time.date|" }

# GET /v1/user/{id}
### Fetch a user [GET]

+ Response authentication (application/json)

  { "username": "|~web.email|", "first": "|~person.first|", "last": "|~person.last|", "address": "|~geo.address|" }

Alternatively, you can be even more lazy, which is encouraged for increased normalization. The following example shows how you can reference and embed fixtures that live on the filesystem using the @ operator.

# POST /v1/auth
### Login a user [POST]

+ Request (application/json)

  |@ auth-req.json|

+ Response 200 (application/json)

  |@ auth-user-res.json|

# GET /v1/user/{id}
### Fetch a user [GET]

+ Response 200 (application/json)

  |@ auth-user-res.json|

It can also be used alongside hercule's tranclusion operator :[]. One advantage is being able to reference URLs:

# POST /v1/auth
### Login a user [POST]

+ Attributes

  |@ auth-req.mson|

+ Request (application/json)

  :[](http://localhost:8000/data/reqs/auth-user-req.json)

+ Response 200 (application/json)

  :[](http://localhost:8000/data/reqs/auth-user-post-res.json)

# GET /v1/user/{id}
### Fetch a user [GET]

+ Response 200 (application/json)

  :[](http://localhost:8000/data/reqs/auth-user-get-res.json)

You may also freely leverage JsonPath in order to transclude fixtures by patterns with the $ operator:

Note

The $ operator will be prefixed to your pattern before being matched. Another way to look at is the text between the | bars will be interpreted as a literal JsonPath.

# POST /v1/auth
### Login a user [POST]

+ Request (application/json)

  |@ auth-req.json|

+ Response 200 (application/json)

  |$..user[0]|

# GET /v1/user/{id}
### Fetch a user [GET]

+ Response 200 (application/json)

  |$..user[0]|

Note

When using $, ensure that your fixtures have either been previously loaded using the @ operator, or by manually injecting your fixtures with hazy.fixture.register before parsing your API Blueprint(s)

Subsets of fixtures may also be targeted. The following GET user fixture is friends with four arbitrary users (selected from tail of list):

# POST /v1/auth
### Login a user [POST]

+ Request (application/json)

  |@ auth-req.json|

+ Response 200 (application/json)

  {"user": "|$..user[0]|", "friends": []}

# GET /v1/user/{id}
### Fetch a user [GET]

+ Response 200 (application/json)

  {"user": "|$..user[0]|", "friends": "|$..user.id[:2]|"}

Command Line

The easiest way to use blot is by running it as a command.

You can specify an API blueprint file to parse and export:

Standard-ized

$ blot compile -i docs.blot.apib --echo > docs.apib

Pretty

$ blot compile -i docs.blot.apib -o docs.apib --pretty

You may also pass in the raw data:

$ blot compile -d 'FORMAT: 1A
# The Simplest API

# GET /message
+ Response 200 (text/json)

{"message": "Hello, |~person.name|!", "id": "|~misc.guid|"}' -o docs.apib --pretty

Project

If you require a lot of flags, or your command just starts to become unwieldy and difficult to read, then a project configuration file can spare you from eye strain:

{
  "host": "http://example.blot.apps.madhax.io",
  "base": ".",
  "docs": {
    "src": "test/fixtures/apiblueprint/hazy.md",
    "dest": "dist/docs/test/fixtures/apiblueprint/hazy.apib",
    "export": true
  },
  "fixtures": {
    "src": "src/fixtures",
    "dest": "dist/fixtures",
    "export": false
  },
  "view": {
    "dest": "dist/api.blot.html",
    "export": true,
    "options": {
      "themeFullWidth": true,
      "themeVariables": "slate"
    },
    "elements": {
      "pluck": ["link", "style", "body > *"]
    },
    "attrs": {},
    "replace": [
      {
        "desc": "replaces positional anchor hrefs with Angular-friendly values",
        "match": "href=\"#([^'\"]+)['\"]", 
        "template": "ng-click=\"scrollTo('|=$sub[0]|')\""
      }
    ]
  },
  "logging": false,
  "pretty": false
}

To build your documentation with a project file, simply provide the path of the configuration as the first argument after your command:

$ blot [command] /path/to/blot.config.json

Note

When a project file is used, blot implicitly sets the configuration file's containing folder as it's current working directory.

An example project can be found in blot/exaxmple/render/blot.json and can be built with the following command (--pretty is of course optional):

$ cd /path/to/blot
$ blot render example/render/blot.json --pretty

Help?

$ blot --help

(thorough documentation coming soon!)

Node

The node module allows you to monkey-patch special functionality and data to your fixtures. You can then inject your monkey-patched hazy pool by setting blot.interpolator, which is used whenever API blueprints are processed.

The following example attaches a created property to all fixtures. It also appends a fixture query parameter to any fixture with a url property (deep):

#! /usr/bin/env node

import hazy from 'hazy'
import blot from 'blot'
import moment from 'moment'

// ensure all fixtures have a created date
hazy.matcher.config({
  path   : '$',
  handle : (fixture) => {
    return Object.assign({created: moment()}, fixture)
  }
})

// ensure any fixture urls are appended with a '&fixture' query param
hazy.matcher.config({
  path   : '$..url',
  handle : (url) => `${url}&fixture=true`
})

// globs and loads data from filesystem into hazy's fixture pool
hazy.fixture.glob('**/fixtures/*.json')

// load api blueprint, process fixtures against configured hazy pool, then export as a static API blueprint file
blot.apib
  .src('documentation.blot.apib')
  .then(apib   => blot.apib.dest(apib.compiled.markdown, 'dist/documentation.apib'))
  .then(result => blot.log().info('done exporting!'))

Install

Basic usage?

$ npm install blot

Contributing?

$ git clone [email protected]:slurmulon/blot.git
$ cd blot
$ npm link

For local installations, you can run a binary of blot via node /path/to/your/project/node_modules/.bin/blot.

Global installation is only recommended for developer convenience. Local installation should always be used in projects and modules to prevent a variety of problems (dependency on machine config, version differences, cache, etc.)

TODO

  • [X] --env CLI flag
  • [X] Static fixture export
  • [ ] Support blot.fixtures.js for automated fixture setup for use in API Blueprint (pre-build)
  • [ ] Incorporate json-where
  • [ ] Incorporate ajv and deref for denormalizing JSON Schemas (tv4 doesn't handle external $ref properly)
  • [ ] Listen for *.blot.* file changes
  • [ ] Current working directory flag
  • [ ] Inheritable project config (more DRY)
  • [ ] Block statements that don't inject whitespace
  • [ ] Support fury.js
  • [ ] Support beforeCompile and afterCompile configuration files (root of project)