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

swiss-docs

v0.7.6

Published

- [swiss-docs](#swiss-docs) - [Setup](#setup) - [Install](#install) - [Add to scripts](#add-to-scripts) - [Syntax](#syntax) - [Meta tag](#meta-tag) - [Name](#name) - [Header depth](#header-depth) - [Subsection](#subsection) - [Priority Level](#priority-le

Downloads

222

Readme

swiss-docs

swiss-docs is a tool for extracting and updating certain JSDoc comments from a repo, and generating a structured, formatted README/markdown document.

The principle is that documentation for a given function/item should not need to be duplicated/maintained in multiple locations, but in one place: in the code, alongside the item itself.

By adding a small amount of meta tags and other small comments, the code becomes self documenting, with room for expansion, examples and more.

Setup

Install

yarn add -D swiss-docs

or

npm install --save-dev swiss-docs

Add to scripts

Add a script to your package.json

{
  "scripts": {
    "docs": "swiss-docs -i src -o README.md"
  }
}

Syntax

Meta tag

The following values can be combined in a single DOCS meta tag:

/**<!-- DOCS: something ###! 10 -->
 * Something
 */

Name

An optional unique name for identifying what the DOCS comment is for. Used for DOCS-ALIAS

Names may contain letters (upper and lower cases), numbers, -, _, $, or .. They cannot contain spaces, and has to start with a letter or _.

/**<!-- DOCS: something -->
 * Something
 */

Header depth

A number of # indicating what level of header to use for the first line of the comment.

Also set the depth of the item in the table of contents

/**<!-- DOCS: ### -->
 * Something
 */
Subsection

A subsection is a segment that has it's own table of contents. Any immediately following segments (after prioritisation) are shown in a mini table of contents under this segment's section of the README, and those 'child' sections are omitted from any Table of Contents that the subsection is shown in.

Subsections may have subsections.

This is a way of reducing the size of the main README table of contents, and dividing it into smaller TOCs throughout the README.

You can indicate that this header is a 'subsection' by adding a ! after the last # (e.g. ###!).

/**<!-- DOCS: ###! -->
 * Something
 */

Priority Level

A number to prioritise the order that comments are output in the markdown.

Lower numbers are shown first

/**<!-- DOCS: 20 -->
 * Shown 2nd
 */
/**<!-- DOCS: 10 -->
 * Shown 1st
 */

Allow JSDoc Updates

Adding a single @ (with spacing either side) in the meta tag will indicate that this comment is okay to be updated by the --jsdoc process.

/**<!-- DOCS: @ -->
 * someFunc
 *
 * You can run --jsdoc, and I'll update
 */
const someFunc = (param: number): number => 1;

Comment content

Title

The first line of the comment content should be the header title as it should be displayed in the README.

Do not include #s as this is managed by the Header depth meta value.

/**<!-- DOCS: something ## -->
 * THIS IS THE TITLE
 */

Accessors

Accessors provide information on where to access the item from (e.g. someObj.aFunc), as it combined with any JSDoc tags to provide a function signature if applicable.

Accessors are optional. If not present, the section is not added to the README.

Accessors must go between the title and the description. They should have an empty space before any after them.

You can have multiple accessors for a single item.

The syntax for accessors in a - bullet points with single back tick \` quote marks. They must be - bullets, not * or +.

/**<!-- DOCS: something ## -->
 * Something
 *
 * - `ACCESSOR_A`
 * - `ACCESSOR_B`
 *
 * This does something
 */

Description

The description describes what the item is and what is does.

Descriptions are optional

/**<!-- DOCS: something ## -->
 * Something
 *
 * - `something`
 *
 * THIS IS THE DESCRIPTION BIT
 */
Example

You can include usage examples in the description of your item. Just use standard markdown code blocks.

/**<!-- DOCS: something ## -->
 * Something
 *
 * - `something`
 *
 * This does something
 *
 * ```typescript
 * something(1); // 2
 * ```
 */

JSDoc tags

You can include JSDoc tags such as @returns and @param to provide information on what an item gives and takes.

To see how this can be updated automatically, see Allow JSDoc Updates.

/**<!-- DOCS: something ## -->
 * Something
 *
 * - `something`
 *
 * This does something
 *
 * ```typescript
 * something(1); // 2
 * ```
 * @param {number} inputNum - a number
 * @returns {number} - A different number
 */

Definitions

README

In the README, wrap where you want the table of contents to be with these comments:

<!-- DOCS: TOC START -->

<!-- DOCS: TOC END -->

Wrap where you want the generated content to be with these comments:

<!-- DOCS: TOC START -->

<!-- DOCS: TOC END -->

Note: anything in these sections will be removed and replaced by the swiss-docs script.

File level

This sets the default values for the file. Everything after the file level defaults to the the values set in the file level definition.

Multiple file level definitions can be used in the same file, splitting the defaults into sections

//<!-- DOCS: ## 100 -->

Comment level

A standard documentation comment. The meta tag must be present to be picked up by the library

First line of the comment should be the header/title of the section. The rest is standard markdown

/**<!-- DOCS: ## 100 -->
 * Title
 *
 * - `A list item`
 *
 * Some description
 */

Aliases

Sometimes multiple sections of code need the same JSDOC comment. Rather than duplicating the comment, and managing 2 versions of the comment, you can use aliases to copy comments in the generated code.

Example:

// file: code.ts

/**<!-- DOCS: example 2 ## -->
 * exampleFunc
 *
 * Something
 */
export const exampleFunc = () => {};

/**<!-- DOCS-ALIAS: example -->*/
export const egFunc = () => {};

Running tsc normally will give this definition file:

// file: code.d.ts

/**<!-- DOCS: example 2 ## -->
 * exampleFunc
 *
 * Something
 */
export declare const exampleFunc: () => void;
/**<!-- DOCS-ALIAS: example -->*/
export declare const egFunc: () => void;

Adding --alias code.d.ts to the swiss-docs will replace any DOCS-ALIAS comments in code.d.ts with their corresponding DOCS comments:

// file: code.d.ts

/**<!-- DOCS: example 2 ## -->
 * exampleFunc
 *
 * Something
 */
export declare const exampleFunc: () => void;
/**<!-- DOCS-ALIAS: example -->
 * exampleFunc
 *
 * Something
 */
export declare const egFunc: () => void;

WARNING: DOCS-ALIAS comments are not included in generated documentation.

WARNING: Is it suggested that you run --alias [x] on generated d.ts files, rather than source code.

Command line options

--src

Alias: -s or -i

The source folder to search for documentation

--output

Alias: -o

The output file to write the markdown to

--template

Alias: -t

An optional template to use for the output markdown

Default: [output]

--header

Alias: -h

The name to use at the top of the table of contents

Default: false

--jsdoc

Alias: -j

Update the JSDoc @ tags in the src files before running the docs.

WARNING: this will make changes to the original source files

WARNING: As each file is transpiled and processed by an external library, this can be very slow

Problems with some JSDoc comments not being updated

To add/update the JSDoc tags, each file is transpiled with the ts-to-jsdoc library (a custom fork called @jackcannon/ts-to-jsdoc), and the result scanned to obtain updated comments to replace the originals with.

This library only seems to handle top-level functions, so the files are pre-processed before the transpile stage to remove any lines that take JSDoc-able sections out of the scope of the library (notably namespaces). These removable sections are indicated by comments in the code.

So this file:

'line 1';

// SWISS-DOCS-JSDOC-REMOVE-START
'REMOVE ME';
// SWISS-DOCS-JSDOC-REMOVE-END

'line 2';

// SWISS-DOCS-JSDOC-REMOVE-NEXT-LINE
'REMOVE ME';

'line 3';

'REMOVE ME'; // SWISS-DOCS-JSDOC-REMOVE-THIS-LINE

'line 4';

'REMOVE ME';
// SWISS-DOCS-JSDOC-REMOVE-PREV-LINE

'line 5';

export namespace Example {
  // SWISS-DOCS-JSDOC-REMOVE-PREV-LINE
  /**
   * A JSDoc comment
   */
  export const aFunc = (param: string): number => 1;
} // SWISS-DOCS-JSDOC-REMOVE-THIS-LINE

gets passed to ts-to-jsdoc as:

'line 1';

'line 2';

'line 3';

'line 4';

'line 5';

/**
 * A JSDoc comment
 */
export const aFunc = (param: string): number => 1;

Default: false

Thanks for reading!