JSPM

  • Created
  • Published
  • Downloads 1065940
  • Score
    100M100P100Q183176F
  • License MIT

Swagger 2.0 parser and validator for Node and browsers

Package Exports

  • swagger-parser
  • swagger-parser/lib/util

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (swagger-parser) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Swagger Parser

Swagger 2.0 parser and validator for Node and browsers

Build Status Dependencies Coverage Status Code Climate Score Codacy Score Inline docs

npm Bower License

Browser Compatibility

| !!! ALPHA NOTICE !!! |----------------------------------- |Swagger Parser 3.0 is in alpha. It is fairly stable, but not fully tested yet, so you may find bugs. Also, please be aware that the API might change slightly before final release.

To install the alpha, run npm install swagger-parser@alpha

Features

  • Parses Swagger specs in JSON or YAML format
  • Validates against the Swagger 2.0 schema and the Swagger 2.0 spec
  • Resolves all $ref pointers, including external files and URLs
  • Can bundle all your Swagger files into a single file that only has internal $ref pointers
  • Can dereference all $ref pointers, giving you a normal JavaScript object that's easy to work with
  • Configurable caching of external files and URLs
  • Tested in Node, IO.js, and all modern web browsers on Mac, Windows, Linux, iOS, and Android
  • Tested on over 100 Google APIs
  • Supports circular references, nested references, back-references, and cross-references
  • Maintains object reference equality &mdash $ref pointers to the same value always resolve to the same object instance

Example

SwaggerParser.validate("my-api.yaml", function(err, api) {
  if (err) {
    console.error(err);
  }
  else {
    console.log("API name: %s, Version: %s", api.info.title, api.info.version);
  }
});

Or use Promises syntax instead. The following example is the same as above:

SwaggerParser.validate("my-api.yaml")
  .then(function(api) {
    console.log("API name: %s, Version: %s", api.info.title, api.info.version);
  })
  .catch(function(err) {
    console.error(err);
  });

Installation

Node

Install using npm:

npm install swagger-parser

Then require it in your code:

var SwaggerParser = require('swagger-parser');

Web Browsers

Install using bower:

bower install swagger-parser

Then reference swagger-parser.js or swagger-parser.min.js in your HTML:

<script src="bower_components/swagger-parser/dist/swagger-parser.js"></script>

Or, if you're using AMD (Require.js), then import it into your module:

define(["swagger-parser"], function(SwaggerParser) { /* your module's code */ })

the API

parse(path, [options], [callback])

  • path (required) - string
    The file path or URL of your Swagger API. The path can be absolute or relative. In Node, the path is relative to process.cwd(). In the browser, it's relative to the URL of the page.

    If you already have the Swagger API as a JavaScript object, then you can pass that instead of a file path.

  • options (optional) - object
    See options below.

  • callback (optional) - function(err, api)
    A callback that will receive the parsed Swagger object, or an error.

  • Return Value: Promise
    See Callbacks vs. Promises below.

Parses the given Swagger API (in JSON or YAML format), and returns it as a JavaScript object. This method does not resolve $ref pointers or dereference anything. It simply parses one file and returns it.

SwaggerParser.parse("my-api.yaml")
  .then(function(api) {
    console.log("API name: %s, Version: %s", api.info.title, api.info.version);
  });

resolve(path, [options], [callback])

  • path (required) - string or object
    The file path or URL of your Swagger API. See the parse method for more info.

  • options (optional) - object
    See options below.

  • callback (optional) - function(err, $refs)
    A callback that will receive a $Refs object.

  • Return Value: Promise
    See Callbacks vs. Promises below.

Resolves all JSON references ($ref pointers) in the given Swagger API. If it references any other files/URLs, then they will be downloaded and resolved as well (unless options.$refs.external is false). This method does not dereference anything. It simply gives you a $Refs object, which is a map of all the resolved references and their values.

SwaggerParser.resolve("my-api.yaml")
  .then(function($refs) {
    // $refs.paths() returns the paths of all the files in your API
    var filePaths = $refs.paths();

    // $refs.get() lets you query parts of your API
    var name = $refs.get("schemas/person.yaml#/properties/name");

    // $refs.set() lets you change parts of your API
    $refs.set("schemas/person.yaml#/properties/favoriteColor/default", "blue");
  });

bundle(path, [options], [callback])

  • path (required) - string or object
    The file path or URL of your Swagger API. See the parse method for more info.

  • options (optional) - object
    See options below.

  • callback (optional) - function(err, api)
    A callback that will receive the bundled Swagger object.

  • Return Value: Promise
    See Callbacks vs. Promises below.

Bundles all referenced files/URLs into a single api that only has internal $ref pointers. This lets you split-up your API however you want while you're building it, but easily combine all those files together when it's time to package or distribute the API to other people. The resulting API size will be small, since it will still contain internal JSON references rather than being fully-dereferenced.

This also eliminates the risk of circular references, so the API can be safely serialized using JSON.stringify().

SwaggerParser.bundle("my-api.yaml")
  .then(function(api) {
    console.log(api.definitions.person); // => {$ref: "#/definitions/schemas~1person.yaml"}
  });

dereference(path, [options], [callback])

  • path (required) - string or object
    The file path or URL of your Swagger API. See the parse method for more info.

  • options (optional) - object
    See options below.

  • callback (optional) - function(err, api)
    A callback that will receive the dereferenced Swagger object.

  • Return Value: Promise
    See Callbacks vs. Promises below.

Dereferences all $ref pointers in the Swagger API, replacing each reference with its resolved value. This results in a Swagger object that does not contain any $ref pointers. Instead, it's a normal JavaScript object tree that can easily be crawled and used just like any other JavaScript object. This is great for programmatic usage, especially when using tools that don't understand JSON references.

The dereference method maintains object reference equality, meaning that all $ref pointers that point to the same object will be replaced with references to the same object. Again, this is great for programmatic usage, but it does introduce the risk of circular references, so be careful if you intend to serialize the API using JSON.stringify(). Consider using the bundle method instead, which does not create circular references.

SwaggerParser.dereference("my-api.yaml")
  .then(function(api) {
    // The `api` object is a normal JavaScript object,
    // so you can easily access any part of the API using simple dot notation
    console.log(api.definitions.person.properties.firstName); // => {type: "string"}
  });

validate(path, [options], [callback])

  • path (required) - string or object
    The file path or URL of your Swagger API. See the parse method for more info.

  • options (optional) - object
    See options below.

  • callback (optional) - function(err, api)
    A callback that will receive the dereferenced and validated Swagger object.

  • Return Value: Promise
    See Callbacks vs. Promises below.

Validates the Swagger API against the Swagger 2.0 schema and/or the Swagger 2.0 spec (depending on the options).

If validation fails, then an error will be passed to the callback function, or the Promise will reject. Either way, the error will contain information about why the API is invalid.

This method calls dereference internally, so the returned Swagger object is fully dereferenced.

SwaggerParser.validate("my-api.yaml")
  .then(function(api) {
    console.log('Yay! The API is valid.');
  })
  .catch(function(err) {
    console.error('Onoes! The API is invalid. ' + err.message);
  });

Options

You can pass an options parameter to any method. You don't need to specify every option - only the ones you want to change.

SwaggerParser.validate("my-api.yaml", {
  allow: {
    json: false,      // Don't allow JSON files
    yaml: true        // Allow YAML files
  },
  $refs: {
    internal: false   // Don't dereference internal $refs, only external
  },
  cache: {
    fs: 1,            // Cache local files for 1 second
    http: 600         // Cache http URLs for 10 minutes
  },
  validate: {
    spec: false       // Don't validate against the Swagger 2.0 spec
  }
});
Option Type Default Description
allow.json bool true Determines whether JSON files are supported
allow.yaml bool true Determines whether YAML files are supported
(note: all JSON files are also valid YAML files)
allow.empty bool true Determines whether it's ok for a $ref pointer to point to an empty file
allow.unknown bool true Determines whether it's ok for a $ref pointer to point to an unknown/unsupported file type (such as HTML, text, image, etc.). The default is to resolve unknown files as a Buffer
$refs.internal bool true Determines whether internal $ref pointers (such as #/definitions/widget) will be dereferenced when calling dereference(). Either way, you'll still be able to get the value using $Refs.get()
$refs.external bool true Determines whether external $ref pointers get resolved/dereferenced. If false, then no files/URLs will be retrieved. Use this if you only want to allow single-file APIs.
validate.schema bool true Determines whether the validate() method validates the API against the Swagger 2.0 schema
validate.spec bool true Determines whether the validate() method validates the API against the Swagger 2.0 spec. This will catch some things that aren't covered by the validate.schema option, such as duplicate parameters, invalid MIME types, etc.
cache.fs number 60 The length of time (in seconds) to cache local files. The default is one minute. Setting to zero will cache forever.
cache.http number 300 The length of time (in seconds) to cache HTTP URLs. The default is five minutes. Setting to zero will cache forever.
cache.https number 300 The length of time (in seconds) to cache HTTPS URLs. The default is five minutes. Setting to zero will cache forever.

API Object

If you create an instance of the SwaggerParser class (rather than just calling the static methods), then the api property gives you easy access to the JSON api. This is the same value that is passed to the callback function (or Promise) when calling the parse, bundle, dereference, or validate methods.

var parser = new SwaggerParser();

parser.api;  // => null

parser.dereference("my-api.yaml")
  .then(function(api) {
    typeof parser.api;     // => "object"

    api === parser.api; // => true
  });

$Refs Object

When you call the resolve method, the value that gets passed to the callback function (or Promise) is a $Refs object. This same object is accessible via the parser.$refs property of SwaggerParser instances.

This object is a map of JSON References ($ref pointers) and their resolved values. It also has several convenient helper methods that make it easy for you to navigate and manipulate the JSON References.

$Refs.paths([types])

  • types (optional) - string (one or more)
    Optionally only return certain types of paths ("fs", "http", "https")

  • Return Value: array of string
    Returns the paths/URLs of all the files in your API (including the main api file).

SwaggerParser.resolve("my-api.yaml")
  .then(function($refs) {
    // Get the paths of ALL files in the API
    $refs.paths();

    // Get the paths of local files only
    $refs.paths("fs");

    // Get all URLs
    $refs.paths("http", "https");
  });

$Refs.values([types])

  • types (optional) - string (one or more)
    Optionally only return values from certain locations ("fs", "http", "https")

  • Return Value: object
    Returns a map of paths/URLs and their correspond values.

SwaggerParser.resolve("my-api.yaml")
  .then(function($refs) {
    // Get ALL paths & values in the API
    // (this is the same as $refs.toJSON())
    var values = $refs.values();

    values["schemas/person.yaml"];
    values["http://company.com/my-api.yaml"];
  });

$Refs.isExpired($ref)

  • $ref (required) - string
    The JSON Reference path, optionally with a JSON Pointer in the hash

  • Return Value: boolean
    Returns true if the given JSON reference has expired (or if it doesn't exist); otherwise, returns false

SwaggerParser.resolve("my-api.yaml")
  .then(function($refs) {
    // Hasn't expired yet
    $refs.isExpired("schemas/person.yaml");   // => false

    // Check again after 10 minutes
    setTimeout(function() {
      $refs.isExpired("schemas/person.yaml"); // => true
    }, 600000);
  });

$Refs.expire($ref)

  • $ref (required) - string
    The JSON Reference path, optionally with a JSON Pointer in the hash

Immediately expires the given JSON reference, so the next time you call a method such as parse or dereference, the file will be refreshed rather than reusing the cached value.

SwaggerParser.resolve("my-api.yaml")
  .then(function($refs) {
    $refs.isExpired("schemas/person.yaml");   // => false

    $refs.expire("schemas/person.yaml");

    $refs.isExpired("schemas/person.yaml");   // => true
  });

$Refs.exists($ref)

  • $ref (required) - string
    The JSON Reference path, optionally with a JSON Pointer in the hash

  • Return Value: boolean
    Returns true if the given path exists in the API; otherwise, returns false

SwaggerParser.resolve("my-api.yaml")
  .then(function($refs) {
    $refs.exists("schemas/person.yaml#/properties/firstName"); // => true
    $refs.exists("schemas/person.yaml#/properties/foobar");    // => false
  });

$Refs.get($ref, [options])

  • $ref (required) - string
    The JSON Reference path, optionally with a JSON Pointer in the hash

  • options (optional) - object
    See options below.

  • Return Value: boolean
    Gets the value at the given path in the API. Throws an error if the path does not exist.

SwaggerParser.resolve("my-api.yaml")
  .then(function($refs) {
    var value = $refs.get("schemas/person.yaml#/properties/firstName");
  });

$Refs.set($ref, value, [options])

  • $ref (required) - string
    The JSON Reference path, optionally with a JSON Pointer in the hash

  • value (required)
    The value to assign. Can be anything (object, string, number, etc.)

  • options (optional) - object
    See options below.

Sets the value at the given path in the API. If the property, or any of its parents, don't exist, they will be created.

SwaggerParser.resolve("my-api.yaml")
  .then(function($refs) {
    $refs.set("schemas/person.yaml#/properties/favoriteColor/default", "blue");
  });

YAML object

This object provides simple YAML parsing functions. Swagger Parser uses this object internally for its own YAML parsing, but it is also exposed so you can use it in your code if needed.

YAML.parse(text)

  • text (required) - string
    The YAML string to be parsed.

  • Return Value:
    Returns the parsed value, which can be any valid JSON type (object, array, string, number, etc.)

This method is similar to JSON.parse(), but it supports YAML in addition to JSON (since any JSON document is also a valid YAML document).

var YAML = SwaggerParser.YAML;
var text = "title: person \n" +
           "required: \n" +
           "  - name \n" +
           "  - age \n" +
           "properties: \n" +
           "  name: \n" +
           "    type: string \n" +
           "  age: \n" +
           "    type: number"

var obj = YAML.parse(text);

// {
//   title: "person",
//   required: ["name", "age"],
//   properties: {
//     name: {
//       type: "string"
//     },
//     age: {
//       type: "number"
//     }
//   }
// }

YAML.stringify(value)

  • value (required)
    The value to be converted to a YAML string. Can be any valid JSON type (object, array, string, number, etc.)

  • Return Value: string
    Returns the a YAML string containing the serialized value

This method is similar to JSON.stringify(), except that it converts a value to a YAML string instead of a JSON string.

var YAML = SwaggerParser.YAML;
var obj = {
  title: "person",
  required: ["name", "age"],
  properties: {
    name: {
      type: "string"
    },
    age: {
      type: "number"
    }
  }
};


var string = YAML.stringify(obj);

// title: person
// required:
//   - name
//   - age
// properties:
//   name:
//     type: string
//   age:
//     type: number

Class methods vs. Instance methods

All of Swagger Parser's methods are available as static (class) methods, and as instance methods. The static methods simply create a new SwaggerParser instance and then call the corresponding instance method. Thus, the following line...

SwaggerParser.validate("my-api.yaml");

... is the same as this:

var parser = new SwaggerParser();
parser.validate("my-api.yaml");

The difference is that in the second example you now have a reference to parser, which means you can access the results (parser.api and parser.$refs) anytime you want, rather than just in the callback function. Also, having a SwaggerParser instance allows you to benefit from caching, so the next time you call parser.resolve(), it won't need to re-download those files again (as long as the cache hasn't expired).

Callbacks vs. Promises

Many people prefer ES6 Promise syntax instead of callbacks. Swagger Parser allows you to use whichever one you prefer. Every method accepts an optional callback and returns a Promise. So pick your poison.

Circular $Refs

Swagger APIs can contain circular $ref pointers, and Swagger Parser fully supports them. Circular references can be resolved and dereferenced just like any other reference. However, if you intend to serialize the dereferenced api as JSON, then you should be aware that JSON.stringify does not support circular references by default, so you will need to use a custom replacer function.

Another option is to use the bundle method rather than the dereference method. Bundling does not result in circular references, because it simply converts external $ref pointers to internal ones.

"person": {
    "properties": {
        "name": {
          "type": "string"
        },
        "spouse": {
          "type": {
            "$ref": "#/person"        // circular reference
          }
        }
    }
}

Contributing

I welcome any contributions, enhancements, and bug-fixes. File an issue on GitHub and submit a pull request.

Building/Testing

To build/test the project locally on your computer:

  1. Clone this repo
    git clone https://github.com/bigstickcarpet/swagger-parser.git

  2. Install dependencies
    npm install

  3. Run the build script
    npm run build

  4. Run the unit tests
    npm run mocha (test in Node)
    npm run karma (test in web browsers)
    npm test (test in Node and browsers, and report code coverage)

License

Swagger Parser is 100% free and open-source, under the MIT license. Use it however you want.