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.
You can install via npm.
npm install @apidevtools/json-schema
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";
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" }
}
}
}
}
}));
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");
Once the JsonSchema
object has been indexed, $ref
s 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");
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.
Contributions, enhancements, and bug-fixes are welcome! Open an issue on GitHub and submit a pull request.
To build the project locally on your computer:
-
Clone this repo
git clone https://github.com/APIDevTools/json-schema.git
-
Install dependencies
npm install
-
Build the code
npm run build
-
Run the tests
npm test
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.
Thanks to these awesome companies for their support of Open Source developers ❤