Skip to content

APIDevTools/json-schema

Repository files navigation

npm License Buy us a tree

Build Status Coverage Status Dependencies

OS and Browser Compatibility

This library provides core JSON Schema functionality and type definitions for APIDevTools projects.

NOTE: This is an internal library that is only intended to be used by other APIDevTools projects. Using it directly is discouraged and unsupported.

Installation

You can install via npm.

npm install @apidevtools/json-schema

Usage

When using this library in Node.js apps, you'll probably want to use CommonJS syntax:

const { JsonSchema } = require("@apidevtools/json-schema");

When using a transpiler such as Babel or TypeScript, or a bundler such as Webpack or Rollup, you can use ECMAScript modules syntax instead:

import { JsonSchema } from "@apidevtools/json-schema";

Populating a JSON Schema

To represent a JSON Schema, you'll need to create an instance of the JsonSchema class, which will contain one or more File objects.

const { JsonSchema, File } = require("@apidevtools/json-schema");

// This creates a JsonSchema object with one File object
let schema = new JsonSchema({
  url: "http://example.com/schema.json",
  data: {
    $schema: "https://json-schema.org/draft/2019-09/schema",
    $id: "person",
    title: "Person",
    properties: {
      name: { $ref: "types.json#/$defs/Name" },
      address: { $ref: "types.json#address" }
    }
  }
});

// Add a second file to the schema
schema.files.push(new File({
  schema,
  url: "http://example.com/types.json",
  data: {
    $defs: {
      Name: {
        title: "Name",
        properties: {
          first: { type: "string" },
          last: { type: "string" }
        }
      },
      Address: {
        $anchor: "address",
        title: "Address",
        properties: {
          street: { type: "string" },
          city: { type: "string" },
          postalCode: { type: "string" }
        }
      }
    }
  }
}));

Indexing the Schema

Once you have a JsonSchema object and all of its File objects, you can "index" the schema. That is, scan the schema's files and identify all the JSON Schema resources, anchors, and references in it.

// Index the schema that we created above 👆
schema.index();

// Now the schema's resources, anchors, and references are populated.
// Let's inspect the $refs in schema.json
let refs = [...schema.rootFile.references];

console.log(refs[0].locationInFile.path);   // /properties/name
console.log(refs[0].value);                 // types.json#/$defs/Name
console.log(refs[0].targetURI.href);        // /path/to/types.json#/$defs/Name

console.log(refs[1].locationInFile.path);   // /properties/address
console.log(refs[1].value);                 // types.json#address
console.log(refs[1].targetURI.href);        // /path/to/types.json#address

Note that indexing a schema can produce very different results, depending on the JSON Schema version. Calling schema.index() without any parameters will auto-detect the JSON Schema version via the $schema keyword. An error will be thrown if auto-detection fails.

An alternative is to explicitly specify the JSON Schema version when calling schema.index():

// Index the schema using Draft 4 rules
schema.index("draft-04");

// Index the schema using Draft 2019-09 rules
schema.index("2019-09");

Resolving References

Once the JsonSchema object has been indexed, $refs in the schema can be resolved. You can call the resolve() method on a Reference object:

// Call the resolve() method of the references we created above 👆

console.log(refs[0].resolve().data);    // { title: "Name", properties: {...}}

console.log(refs[1].resolve().data);    // { title: "Address", properties: {...}}

You can also use the JsonSchema.resolve() method to resolve arbitrary references within the schema:

// Resolving this reference entail traversing schema.json and types.json
let resolution = schema.resolve("http://example.com/person#/properties/name/properties/first");

// The Resolution object contains the final resolved value, as well as each resolution step along the way
console.log(resolution.data);                         // { type: "string" }
console.log(resolution.locationInFile.path);          // /$defs/Name/properties/first
console.log(`${resolution.previousStep.reference}`);  // $ref: http://example.com/types.json#/$defs/Name

Just like with the index() method, the behavior of the resolve() method depends on the JSON Schema version. By default, it will attempt to auto-detect the version, but you can explicitly specify it instead:

// Resolve a reference using Draft 4 rules
refs[0].resolve("draft-04");

// Resolve a URI using Draft 2019-09 rules
schema.resolve("http://example.com/person", "2019-09");

Browser support

This library supports recent versions of every major web browser. Older browsers may require Babel and/or polyfills.

To use in a browser, you'll need to use a bundling tool such as Webpack, Rollup, Parcel, or Browserify. Some bundlers may require a bit of configuration, such as setting browser: true in rollup-plugin-resolve.

Contributing

Contributions, enhancements, and bug-fixes are welcome! Open an issue on GitHub and submit a pull request.

Building

To build the project locally on your computer:

  1. Clone this repo
    git clone https://github.com/APIDevTools/json-schema.git

  2. Install dependencies
    npm install

  3. Build the code
    npm run build

  4. Run the tests
    npm test

License

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

This package is Treeware. If you use it in production, then we ask that you buy the world a tree to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats.

Big Thanks To

Thanks to these awesome companies for their support of Open Source developers ❤

GitHub NPM Coveralls Travis CI SauceLabs

About

Internal JSON Schema library used by APIDevTools

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published