Security News
Weekly Downloads Now Available in npm Package Search Results
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
:umbrella: The DRY documentation build tool
API Blueprint + Transclusion + Queries = Ultra-DRY Docs
bunyan
) and pretty logs for sane debuggingblot 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.
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.
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 withhazy.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]|"}
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
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
$ blot --help
(thorough documentation coming soon!)
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!'))
Basic usage?
$ npm install blot
Contributing?
$ git clone git@github.com: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.)
--env
CLI flagblot.fixtures.js
for automated fixture setup for use in API Blueprint (pre-build)json-where
ajv
and deref
for denormalizing JSON Schemas (tv4 doesn't handle external $ref
properly)*.blot.*
file changesbeforeCompile
and afterCompile
configuration files (root of project)FAQs
The DRY documentation builder
The npm package blot receives a total of 3 weekly downloads. As such, blot popularity was classified as not popular.
We found that blot demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
Security News
A Stanford study reveals 9.5% of engineers contribute almost nothing, costing tech $90B annually, with remote work fueling the rise of "ghost engineers."
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.