Skip to content

Convert standard JSDoc @typedef comment blocks into JSON Schema (with support for nonstandard expansions).

License

Notifications You must be signed in to change notification settings

brettz9/jsdoc-jsonschema

Repository files navigation

npm Dependencies devDependencies

Build Status testing badge coverage badge

Known Vulnerabilities Total Alerts Code Quality: Javascript

Licenses badge

(see also licenses for dev. deps.)

issuehunt-to-marktext

jsdoc-jsonschema

Convert standard JSDoc @typedef comment blocks into JSON Schema (with support for nonstandard expansions).

Use cases

  • Validating the arguments passed to one's code at run-time
  • For command-line scripts, one may need to apply schemas to the strings passed in in order to get typed info back out.

JSDoc is needed within code for good API docs anyways (one could build them from JSON Schema, but then they wouldn't be integrated into one's code), but since the information is redundant with JSON Schema, it can save time from having to build both.

Current features

JSDoc JSON Schema Notes
@typedef {type: 'object'}
/** Some desc.\n\n* @typedef */ {type: 'object', description: 'Some desc.'}
@typedef typeName {type: 'object', title: 'typeName'}
@property {integer} propName {properties: {propName: {type: 'integer'}}, required: ['propName']}
@property {3|4|5} propName {properties: {propName: {type: 'number', enum: [3, 4, 5]}}, required: ['propName']} Can force to integer type
@typedef {3|4|5} {type: 'number', enum: [3, 4, 5]} Can force to integer type
@typedef {SomeType & (AnotherType | YetAnotherType)} {allOf: [{classRelation: 'is-a', $ref: '$defs/SomeType'}, {anyOf: [{classRelation: 'is-a', $ref: '$defs/AnotherType'}, {classRelation: 'is-a', $ref: '$defs/YetAnotherType'}]}]} Inner parenthesized unions and/or intersections
@property {integer} [propName] Prop desc. {properties: {propName: {type: 'integer', description: 'Prop desc.'}}} Supported JSON Schema types: 'null', 'boolean', 'object', 'array', 'number', 'string', 'integer'; with tolerateCase option not disabled, will allow Integer, etc., as well
@property {string[]} [propName] Prop. desc. {properties: {propName: {type: 'array', description: 'Prop desc.', items: {type: 'string'}}}}
`@property {string[] number[]} [propName] Prop. desc.` {properties: {propName: {type: 'array', description: 'Prop desc.', items: {anyOf: [{type: 'string'}, {type: 'number'}]}}}}

FAQ

Why not just use JSON Schema?

While JSON Schema is nicely structured for consumption by JavaScript, it is not integrated within one's code.

And when the schema is discoverable within one's code in the context where it is defined and maintained, one is surely more likely to keep it up to date.

Won't you become unable to express certain JSON Schema features coming from JSDoc?

JSDoc already has certain standard tags that can express certain JSON schema features like type and properties. We want to leverage those standard features where they exist.

However, JSDoc can support definition of custom tags, so if necessary, we can add certain features that can be converted into other JSON Schema features.

Installation

npm i jsdoc-jsonschema

Usage

import {jsdocToJsonSchema} from 'jsdoc-jsonschema';

jsdocToJsonSchema(`
  /**
   * @typedef {PlainObject} ParentType
   * @property {number} numName
   */
`);
{
  "type": "object",
  "properties": {
    "numName": {
      "type": "number"
    }
  }
}

Options

As a second argument, one can supply an options object with the following properties:

  • $defs - Boolean (default false) on whether to produce a schema with $defs. Expected when seeking to build is-a structures (with a single root).
  • preferInteger - Boolean (default false) on whether to prefer integer as a schema type when the number has no decimal value.
  • tolerateCase - Boolean (default true) on whether to allow types defined in different casing, e.g., Object, to avoid throwing and be converted to their lower-case counterpart understood by JSON Schema.
  • throwOnUnrecognizedName - Boolean (default true) on whether to throw upon encountering a type that is not a JSON-schema type (unless a custom type is supplied).
  • types - Object (defaults to {PlainObject: {type: 'object'}}) whose keys are custom type names and whose values are objects with type and/or format. If one of the custom types is found in a jsdoc type, its conversion to JSON Schema will result in the object's type and/or format.

CLI

badges/cli.svg

Scope

This project does not aim to convert other similar sources such as TypeScript definition files (though see the links below for that).

However, it is, for now, using jsdoctypeparser (over the standard jsdoc catharsis) so that, in theory, we could allow conversion of TypeScript-specific types within jsdoc comments into suitable schema features (e.g., intersections).

See also

To-dos

  1. Switch from jsdoctypeparser to jsdoc-type-pratt-parser
  2. Get binary to support saving separate typedefs within a file to different output files
  3. Add whitelist option so only get desired typedef and its parents out of a file (may be useful with command-line-basics).
  4. Add support in json-schema-to-jsdoc (#41) for @typedef's referencing other @typedef's to complete commented out sanity checks in tests; resume using stable version once may be merged

Lower-priority to-dos

  1. Support file globs and output directory
  2. Get working with mixed union types (and for TS, intersection types)
  3. Add mixed literals as enum with type array
  4. Nested types, e.g., nullable
  5. Use title with @property despite being redundant with properties key?
  6. Convert TS negated type to not?
  7. Option to read from file, optionally filtering out only the @typedef's of interest (by whitelist and/or blacklist)
  8. Option to save to file (based on @typedef tag name and/or other custom tags?)
  9. Add method to support parsing entire import/require pipeline for @typedef's for conversion to schemas (could use es-file-traverse)

About

Convert standard JSDoc @typedef comment blocks into JSON Schema (with support for nonstandard expansions).

Resources

License

Stars

Watchers

Forks

Packages

No packages published