Awesome
Getdocs
Getdocs is like JSDoc or documentation.js, running over ES6 code to extract information and inline documentation in order to generate docs, but without all the @s. It takes source files and outputs JSON.
For example, if you have this file, foo.js
:
// :: (number, number) → number
// Add two numbers
export function plus(a, b = 2) {
return a + b
}
You can say getdocs foo.js
to get this JSON:
{
"plus": {
"type": "Function",
"params": [
{
"type": "number",
"name": "a"
},
{
"type": "number",
"default": "2",
"optional": true,
"name": "b"
}
],
"returns": { "type": "number" },
"description": "Add two numbers",
"exported": true
}
}
The idea is to then feed this into a system (can be a simple set of templates) that massages it into actual human-readable documention files.
A getdocs doc comment starts with a double colon, optionally prefixed
with a name (foo::
) and followed by a type. It can be either a block
comment or a continuous sequence of line comments. When you don't want
to specify a type, for example because the type can be inferred from
the code (as with a class declaration), you can write a single dash
after the colons, instead of a type.
When no name is given, such a doc comment applies to the next program element after it. That element should be something with a name, like a variable, function, or class declaration, or an assignment that can be statically resolved.
The documented items found in the files passed to getdocs will be
returned as part of a big JSON object. Nesting is only applied for
class and object properties, where the properties are moved under the
properties
object of the item they are part of. A single namespace
is assumed for the documented identifiers in the group of files.
Inside a doc comment, properties of the thing being defined can be added by writing nested, indented doc comments. For example:
// Plugin:: interface
//
// Objects conforming to the plugin interface can be plugged into a
// Foo
//
// mount:: (Foo) → bool
// Mount the plugin in this Foo. The return value indicates whether
// the mount succeeded.
//
// unmount:: (Foo)
// Unmount the plugin from a Foo.
Further nesting below such a property (by adding more indentation) is supported.
Type syntax
A type can be:
-
A JavaScript identifier, optionally followed by any number of properties, which are a dot character followed by a JavaScript identifier. A type name can be followed by a list of type parameters, between angle brackets, as in
Object<string>
(an object whose properties hold string values). -
An array type, which is a type wrapped in
[
and]
.[x]
is equivalent toArray<x>
. -
A function type, which is written as a parenthesized list of argument types. Each argument type may optionally be prefixed with an argument name, which is an identifier followed by a colon. When an argument is prefixed by the string
...
, it is marked as arest
argument. After the closing parenthesis, an optional return type may appear after an arrow, written either→
or->
. -
A nullable type, written as a question mark followed by a type.
-
An unspecified or “any” type, written as an asterisk
*
. -
An object type, written as a list of properties wrapped in
{
and}
braces. Each property must start with an identifier, followed by a colon, followed by a type. -
A string literal, enclosed by double quotes, or a number literal.
-
A type followed by
extends
followed by another type, to indicate a sub-type.
Here are some examples of types:
-
Math.pow
:(base: number, exponent: number) → number
-
Element.insertBefore
:(newNode: Node, before: ?Node) → Node
-
console.log
:(...data: *)
-
A pair of coordinates:
{x: number, y: number}
-
An array of strings:
[string]
-
An array of numbers or a string:
union<[number], string>
(what the nameunion
means isn't something getdocs is aware of, but you could use it for union types, and maybe render it as[number] | string
in your output).
Tags
It is possible to add tags to a documented item. These are words
prefixed with a #
character, appearing at the start of the comment —
that is, immediately after the type.
A tag like #deprecated
, for example, will result in a $deprecated: "true"
property on the given item. The property is named by
prepending the tag's name with a dollar sign.
You can give tags an explicit value other than "true"
by writing an
=
character followed either by a word (a sequence of characters
without whitespace) or a quoted JavaScript-style string. For example
#chapter=selection
or #added="2.1.0"
.
The #static
tag can be used to indicate that a given class member is
static (which is only necessary for doc comments that aren't tied to a
syntactic element in the code).
Output JSON
The returned object maps item names to item descriptions. The following properties can appear in a description for a documented item:
-
description: The doc comment for the item.
-
loc: A
{line, column, file}
object pointing at the start of the item. -
exported: Set if the item is exported using ES6 module syntax.
-
constructor: For classes with a documented constructor, this points at the constructor function.
-
extends: Holds the type of the supertype of a class or other sub-type.
-
staticProperties: For classes, this holds properties and methods that appear directly on the constructor.
In addition, they may have these properties, which can also appear on nested types:
-
type: The name of the type. Instances of classes should use the (capitalized) class name. Builtin types will have names like
Array
orFunction
. Getdocs does not prescribe a naming of primitive types, but for consistency I recommend you usenumber
,string
, andbool
. -
properties: An object mapping property names to types.
-
params: For function types, this holds an array of parameter types. Parameter types can have these additional properties:
-
name: The name of the parameter.
-
rest: Set when this is a rest parameter.
-
default: The default value of the parameter (as a raw source string).
-
-
returns: For function types, this holds the type that is returned.
-
typeParams: For array types or named types with parameters (angle bracket syntax), this holds an array of parameter types.
-
optional: Set for nullable types.
-
id: The path to this type. For a top-level variable
foo
this'll be"foo"
, for the type of the propertybar
underfoo
, it'll be"foo.bar"
, and so on.
Interface
The module exports the following function:
gather
: (code: string, options: Object) → Object
It takes a code file, extracts the docs, and returns an object describing the documented items.
Options can have the following properties:
-
filename
: string
The filename of the given code. Required. -
items
: ?Object
An existing items object to add the items found in the given code to. -
onComment
: ?(block: bool, text: string, start: number, end: number, startPos: Object, endPos: Object)
Will be called for each comment in the code, if given.
parseType
: (input: string, start: number, loc: {file: string, line: number}) → {type: Object, end: number}
Parse a type in getdocs syntax into its object representation. start
indicates where in the string the parsing should start. The returned
object tells you where the type ended.
Will throw a SyntaxError
when the type isn't valid.
stripComment
: (comment: string) → string
Strips leading indentation and asterisks (as in the common block comment style where each line gets an asterisk) from a string.