{"id":13433498,"url":"https://github.com/hyperjump-io/json-schema","last_synced_at":"2025-07-28T00:04:35.592Z","repository":{"id":38246103,"uuid":"247144474","full_name":"hyperjump-io/json-schema","owner":"hyperjump-io","description":"JSON Schema Validation, Annotation, and Bundling. Supports Draft 04, 06, 07, 2019-09, 2020-12, OpenAPI 3.0, and OpenAPI 3.1","archived":false,"fork":false,"pushed_at":"2025-07-13T04:16:08.000Z","size":785,"stargazers_count":269,"open_issues_count":5,"forks_count":26,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-07-15T15:56:10.185Z","etag":null,"topics":["json-schema"],"latest_commit_sha":null,"homepage":"https://json-schema.hyperjump.io/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hyperjump-io.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["hyperjump-io"]}},"created_at":"2020-03-13T19:10:55.000Z","updated_at":"2025-07-13T04:16:07.000Z","dependencies_parsed_at":"2023-11-20T20:25:32.784Z","dependency_job_id":"eba35587-e0e4-4348-bcf4-bd8f8b90a4f4","html_url":"https://github.com/hyperjump-io/json-schema","commit_stats":{"total_commits":141,"total_committers":1,"mean_commits":141.0,"dds":0.0,"last_synced_commit":"007157c16646f1f6ce34ecbce0f542082467ca43"},"previous_names":[],"tags_count":107,"template":false,"template_full_name":null,"purl":"pkg:github/hyperjump-io/json-schema","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperjump-io%2Fjson-schema","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperjump-io%2Fjson-schema/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperjump-io%2Fjson-schema/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperjump-io%2Fjson-schema/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hyperjump-io","download_url":"https://codeload.github.com/hyperjump-io/json-schema/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperjump-io%2Fjson-schema/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265544711,"owners_count":23785680,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["json-schema"],"created_at":"2024-07-31T02:01:27.274Z","updated_at":"2025-07-28T00:04:35.580Z","avatar_url":"https://github.com/hyperjump-io.png","language":"JavaScript","funding_links":["https://github.com/sponsors/hyperjump-io"],"categories":["JavaScript","others"],"sub_categories":[],"readme":"# Hyperjump - JSON Schema\n\nA collection of modules for working with JSON Schemas.\n\n* Validate JSON-compatible values against a JSON Schemas\n  * Dialects: draft-2020-12, draft-2019-09, draft-07, draft-06, draft-04\n  * Schemas can reference other schemas using a different dialect\n  * Work directly with schemas on the filesystem or HTTP\n* OpenAPI\n  * Versions: 3.0, 3.1\n  * Validate an OpenAPI document\n  * Validate values against a schema from an OpenAPI document\n* Create custom keywords, vocabularies, and dialects\n* Bundle multiple schemas into one document\n  * Uses the process defined in the 2020-12 specification but works with any\n    dialect.\n* Utilities for building non-validation JSON Schema tooling\n* Utilities for working with annotations\n\n## Install\n\nIncludes support for node.js/bun.js (ES Modules, TypeScript) and browsers (works\nwith CSP\n[`unsafe-eval`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#unsafe_eval_expressions)).\n\n### Node.js\n\n```bash\nnpm install @hyperjump/json-schema\n```\n\n### TypeScript\n\nThis package uses the package.json \"exports\" field. [TypeScript understands\n\"exports\"](https://devblogs.microsoft.com/typescript/announcing-typescript-4-5-beta/#packagejson-exports-imports-and-self-referencing),\nbut you need to change a couple settings in your `tsconfig.json` for it to work.\n\n```jsonc\n    \"module\": \"Node16\", // or \"NodeNext\"\n    \"moduleResolution\": \"Node16\", // or \"NodeNext\"\n```\n\n### Versioning\n\nThe API for this library is divided into two categories: Stable and\nExperimental. The Stable API follows semantic versioning, but the Experimental\nAPI may have backward-incompatible changes between minor versions.\n\nAll experimental features are segregated into exports that include the word\n\"experimental\" so you never accidentally depend on something that could change\nor be removed in future releases.\n\n## Validation\n\n### Usage\n\nThis library supports many versions of JSON Schema. Use the pattern\n`@hyperjump/json-schema/*` to import the version you need.\n\n```javascript\nimport { registerSchema, validate } from \"@hyperjump/json-schema/draft-2020-12\";\n```\n\nYou can import support for additional versions as needed.\n\n```javascript\nimport { registerSchema, validate } from \"@hyperjump/json-schema/draft-2020-12\";\nimport \"@hyperjump/json-schema/draft-07\";\n```\n\n**Note**: The default export (`@hyperjump/json-schema`) is reserved for the\nstable version of JSON Schema that will hopefully be released in near future.\n\n**Validate schema from JavaScript**\n\n```javascript\nregisterSchema({\n  $schema: \"https://json-schema.org/draft/2020-12/schema\",\n  type: \"string\"\n}, \"http://example.com/schemas/string\");\n\nconst output = await validate(\"http://example.com/schemas/string\", \"foo\");\nif (output.valid) {\n  console.log(\"Instance is valid :-)\");\n} else {\n  console.log(\"Instance is invalid :-(\");\n}\n```\n\n**Compile schema**\n\nIf you need to validate multiple instances against the same schema, you can\ncompile the schema into a reusable validation function.\n\n```javascript\nconst isString = await validate(\"http://example.com/schemas/string\");\nconst output1 = isString(\"foo\");\nconst output2 = isString(42);\n```\n\n**Fetching schemas**\n\nSchemas that are available on the web can be loaded automatically without\nneeding to load them manually.\n\n```javascript\nconst output = await validate(\"http://example.com/schemas/string\", \"foo\");\n```\n\nWhen running on the server, you can also load schemas directly from the\nfilesystem. When fetching from the file system, there are limitations for\nsecurity reasons. You can only reference a schema identified by a file URI\nscheme (**file**:///path/to/my/schemas) from another schema identified by a file\nURI scheme. Also, a schema is not allowed to self-identify (`$id`) with a\n`file:` URI scheme.\n\n```javascript\nconst output = await validate(`file://${__dirname}/string.schema.json`, \"foo\");\n```\n\nIf the schema URI is relative, the base URI in the browser is the browser\nlocation and the base URI on the server is the current working directory. This\nis the preferred way to work with file-based schemas on the server.\n\n```javascript\nconst output = await validate(`./string.schema.json`, \"foo\");\n```\n\nYou can add/modify/remove support for any URI scheme using the [plugin\nsystem](https://github.com/hyperjump-io/browser/#uri-schemes) provided by\n`@hyperjump/browser`.\n\n**OpenAPI**\n\nThe OpenAPI 3.0 and 3.1 meta-schemas are pre-loaded and the OpenAPI JSON Schema\ndialects for each of those versions is supported. A document with a Content-Type\nof `application/openapi+json` (web) or a file extension of `openapi.json`\n(filesystem) is understood as an OpenAPI document.\n\nUse the pattern `@hyperjump/json-schema/*` to import the version you need. The\navailable versions are `openapi-3-0` for 3.0 and `openapi-3-1` for 3.1.\n\n```javascript\nimport { validate } from \"@hyperjump/json-schema/openapi-3-1\";\n\n\n// Validate an OpenAPI document\nconst output = await validate(\"https://spec.openapis.org/oas/3.1/schema-base\", openapi);\n\n// Validate an instance against a schema in an OpenAPI document\nconst output = await validate(\"./example.openapi.json#/components/schemas/foo\", 42);\n```\n\nYAML support isn't built in, but you can add it by writing a\n[MediaTypePlugin](https://github.com/hyperjump-io/browser/#media-types). You can\nuse the one at `lib/openapi.js` as an example and replace the JSON parts with\nYAML.\n\n**Media types**\n\nThis library uses media types to determine how to parse a retrieved document. It\nwill never assume the retrieved document is a schema. By default it's configured\nto accept documents with a `application/schema+json` Content-Type header (web)\nor a `.schema.json` file extension (filesystem).\n\nYou can add/modify/remove support for any media-type using the [plugin\nsystem](https://github.com/hyperjump-io/browser/#media-types) provided by\n`@hyperjump/browser`. The following example shows how to add support for JSON\nSchemas written in YAML.\n\n```javascript\nimport YAML from \"yaml\";\nimport contentTypeParser from \"content-type\";\nimport { addMediaTypePlugin } from \"@hyperjump/browser\";\nimport { buildSchemaDocument } from \"@hyperjump/json-schema/experimental\";\n\n\naddMediaTypePlugin(\"application/schema+yaml\", {\n  parse: async (response) =\u003e {\n    const contentType = contentTypeParser.parse(response.headers.get(\"content-type\") ?? \"\");\n    const contextDialectId = contentType.parameters.schema ?? contentType.parameters.profile;\n\n    const foo = YAML.parse(await response.text());\n    return buildSchemaDocument(foo, response.url, contextDialectId);\n  },\n  fileMatcher: (path) =\u003e path.endsWith(\".schema.yml\")\n});\n```\n\n### API\n\nThese are available from any of the exports that refer to a version of JSON\nSchema, such as `@hyperjump/json-schema/draft-2020-12`.\n\n* **registerSchema**: (schema: object, retrievalUri?: string, defaultDialectId?: string) =\u003e void\n\n    Add a schema the local schema registry. When this schema is needed, it will\n    be loaded from the register rather than the filesystem or network. If a\n    schema with the same identifier is already registered, an exception will be\n    throw.\n* **unregisterSchema**: (uri: string) =\u003e void\n\n    Remove a schema from the local schema registry.\n* **getAllRegisteredSchemaUris**: () =\u003e string[]\n\n    This function returns the URIs of all registered schemas\n* **hasSchema**: (uri: string) =\u003e boolean\n\n    Check if a schema with the given URI is already registered.\n* _(deprecated)_ **addSchema**: (schema: object, retrievalUri?: string, defaultDialectId?: string) =\u003e void\n\n    Load a schema manually rather than fetching it from the filesystem or over\n    the network. Any schema already registered with the same identifier will be\n    replaced with no warning.\n* **validate**: (schemaURI: string, instance: any, outputFormat: ValidationOptions | OutputFormat = FLAG) =\u003e Promise\\\u003cOutputUnit\u003e\n\n    Validate an instance against a schema. This function is curried to allow\n    compiling the schema once and applying it to multiple instances.\n* **validate**: (schemaURI: string) =\u003e Promise\\\u003c(instance: any, outputFormat: ValidationOptions | OutputFormat = FLAG) =\u003e OutputUnit\u003e\n\n    Compiling a schema to a validation function.\n* **FLAG**: \"FLAG\"\n\n    An identifier for the `FLAG` output format as defined by the 2019-09 and\n    2020-12 specifications.\n* **InvalidSchemaError**: Error \u0026 { output: OutputUnit }\n\n    This error is thrown if the schema being compiled is found to be invalid.\n    The `output` field contains an `OutputUnit` with information about the\n    error. You can use the `setMetaSchemaOutputFormat` configuration to set the\n    output format that is returned in `output`.\n* **setMetaSchemaOutputFormat**: (outputFormat: OutputFormat) =\u003e void\n\n    Set the output format used for validating schemas.\n* **getMetaSchemaOutputFormat**: () =\u003e OutputFormat\n\n    Get the output format used for validating schemas.\n* **setShouldMetaValidate**: (isEnabled: boolean) =\u003e void\n\n    Enable or disable validating schemas.\n* **getShouldMetaValidate**: (isEnabled: boolean) =\u003e void\n\n    Determine if validating schemas is enabled.\n\n**Type Definitions**\n\nThe following types are used in the above definitions\n\n* **OutputFormat**: **FLAG**\n\n    Only the `FLAG` output format is part of the Stable API. Additional [output\n    formats](#output-formats) are included as part of the Experimental API.\n* **OutputUnit**: { valid: boolean }\n\n    Output is an experimental feature of the JSON Schema specification. There\n    may be additional fields present in the OutputUnit, but only the `valid`\n    property should be considered part of the Stable API.\n* **ValidationOptions**:\n\n    * outputFormat?: OutputFormat\n    * plugins?: EvaluationPlugin[]\n\n## Bundling\n\n### Usage\n\nYou can bundle schemas with external references into a single deliverable using\nthe official JSON Schema bundling process introduced in the 2020-12\nspecification. Given a schema with external references, any external schemas\nwill be embedded in the schema resulting in a Compound Schema Document with all\nthe schemas necessary to evaluate the given schema in a single JSON document.\n\nThe bundling process allows schemas to be embedded without needing to modify any\nreferences which means you get the same output details whether you validate the\nbundle or the original unbundled schemas.\n\n```javascript\nimport { registerSchema } from \"@hyperjump/json-schema/draft-2020-12\";\nimport { bundle } from \"@hyperjump/json-schema/bundle\";\n\n\nregisterSchema({\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n\n  \"type\": \"object\",\n  \"properties\": {\n    \"foo\": { \"$ref\": \"/string\" }\n  }\n}, \"https://example.com/main\");\n\nregisterSchema({\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n\n  \"type\": \"string\"\n}, \"https://example.com/string\");\n\nconst bundledSchema = await bundle(\"https://example.com/main\"); // {\n//   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n//\n//   \"type\": \"object\",\n//   \"properties\": {\n//     \"foo\": { \"$ref\": \"/string\" }\n//   },\n//\n//   \"$defs\": {\n//     \"string\": {\n//       \"$id\": \"https://example.com/string\",\n//       \"type\": \"string\"\n//     }\n//   }\n// }\n```\n\n### API\n\nThese are available from the `@hyperjump/json-schema/bundle` export.\n\n* **bundle**: (uri: string, options: Options) =\u003e Promise\\\u003cSchemaObject\u003e\n\n    Create a bundled schema starting with the given schema. External schemas\n    will be fetched from the filesystem, the network, or the local schema\n    registry as needed.\n\n    Options:\n     * alwaysIncludeDialect: boolean (default: false) -- Include dialect even\n       when it isn't strictly needed\n     * definitionNamingStrategy: \"uri\" | \"uuid\" (default: \"uri\") -- By default\n       the name used in definitions for embedded schemas will match the\n       identifier of the embedded schema. Alternatively, you can use a UUID\n       instead of the schema's URI.\n     * externalSchemas: string[] (default: []) -- A list of schemas URIs that\n       are available externally and should not be included in the bundle.\n\n## Experimental\n\n### Output Formats\n\n**Change the validation output format**\n\nThe `FLAG` output format isn't very informative. You can change the output\nformat used for validation to get more information about failures. The official\noutput format is still evolving, so these may change or be replaced in the\nfuture. This implementation currently supports the BASIC and DETAILED output\nformats.\n\n```javascript\nimport { BASIC } from \"@hyperjump/json-schema/experimental\";\n\n\nconst output = await validate(\"https://example.com/schema1\", 42, BASIC);\n```\n\n**Change the schema validation output format**\n\nThe output format used for validating schemas can be changed as well.\n\n```javascript\nimport { validate, setMetaSchemaOutputFormat } from \"@hyperjump/json-schema/draft-2020-12\";\nimport { BASIC } from \"@hyperjump/json-schema/experimental\";\n\n\nsetMetaSchemaOutputFormat(BASIC);\ntry {\n  const output = await validate(\"https://example.com/invalid-schema\");\n} catch (error) {\n  console.log(error.output);\n}\n```\n\n### Custom Keywords, Vocabularies, and Dialects\n\nIn order to create and use a custom keyword, you need to define your keyword's\nbehavior, create a vocabulary that includes that keyword, and then create a\ndialect that includes your vocabulary.\n\nSchemas are represented using the\n[`@hyperjump/browser`](https://github.com/hyperjump-io/browser) package. You'll\nuse that API to traverse schemas. `@hyperjump/browser` uses async generators to\niterate over arrays and objects. If you like using higher order functions like\n`map`/`filter`/`reduce`, see\n[`@hyperjump/pact`](https://github.com/hyperjump-io/pact) for utilities for\nworking with generators and async generators.\n\n```javascript\nimport { registerSchema, validate } from \"@hyperjump/json-schema/draft-2020-12\";\nimport { addKeyword, defineVocabulary, Validation } from \"@hyperjump/json-schema/experimental\";\nimport * as Browser from \"@hyperjump/browser\";\n\n\n// Define a keyword that's an array of schemas that are applied sequentially\n// using implication: A -\u003e B -\u003e C -\u003e D\naddKeyword({\n  id: \"https://example.com/keyword/implication\",\n\n  compile: async (schema, ast) =\u003e {\n    const subSchemas = [];\n    for await (const subSchema of Browser.iter(schema)) {\n      subSchemas.push(Validation.compile(subSchema, ast));\n    }\n    return subSchemas;\n\n    // Alternative using @hyperjump/pact\n    // return pipe(\n    //   Browser.iter(schema),\n    //   asyncMap((subSchema) =\u003e Validation.compile(subSchema, ast)),\n    //   asyncCollectArray\n    // );\n  },\n\n  interpret: (implies, instance, context) =\u003e {\n    return implies.reduce((valid, schema) =\u003e {\n      return !valid || Validation.interpret(schema, instance, context);\n    }, true);\n  }\n});\n\n// Create a vocabulary with this keyword and call it \"implies\"\ndefineVocabulary(\"https://example.com/vocab/logic\", {\n  \"implies\": \"https://example.com/keyword/implication\"\n});\n\n// Create a vocabulary schema for this vocabulary\nregisterSchema({\n  \"$id\": \"https://example.com/meta/logic\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n\n  \"$dynamicAnchor\": \"meta\",\n  \"properties\": {\n    \"implies\": {\n      \"type\": \"array\",\n      \"items\": { \"$dynamicRef\": \"meta\" },\n      \"minItems\": 2\n    }\n  }\n});\n\n// Create a dialect schema adding this vocabulary to the standard JSON Schema\n// vocabularies\nregisterSchema({\n  \"$id\": \"https://example.com/dialect/logic\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n\n  \"$vocabulary\": {\n    \"https://json-schema.org/draft/2020-12/vocab/core\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/applicator\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/unevaluated\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/validation\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/meta-data\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/format-annotation\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/content\": true\n    \"https://example.com/vocab/logic\": true\n  },\n\n  \"$dynamicAnchor\": \"meta\",\n\n  \"allOf\": [\n    { \"$ref\": \"https://json-schema.org/draft/2020-12/schema\" },\n    { \"$ref\": \"/meta/logic\" }\n  ]\n});\n\n// Use your dialect to validate a JSON instance\nregisterSchema({\n  \"$schema\": \"https://example.com/dialect/logic\",\n\n  \"type\": \"number\",\n  \"implies\": [\n    { \"minimum\": 10 },\n    { \"multipleOf\": 2 }\n  ]\n}, \"https://example.com/schema1\");\nconst output = await validate(\"https://example.com/schema1\", 42);\n```\n\n### Custom Meta Schema\n\nYou can use a custom meta-schema to restrict users to a subset of JSON Schema\nfunctionality. This example requires that no unknown keywords are used in the\nschema.\n\n```javascript\nregisterSchema({\n  \"$id\": \"https://example.com/meta-schema1\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n\n  \"$vocabulary\": {\n    \"https://json-schema.org/draft/2020-12/vocab/core\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/applicator\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/unevaluated\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/validation\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/meta-data\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/format-annotation\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/content\": true\n  },\n\n  \"$dynamicAnchor\": \"meta\",\n\n  \"$ref\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"unevaluatedProperties\": false\n});\n\nregisterSchema({\n  $schema: \"https://example.com/meta-schema1\",\n  type: \"number\",\n  foo: 42\n}, \"https://example.com/schema1\");\n\nconst output = await validate(\"https://example.com/schema1\", 42); // Expect InvalidSchemaError\n```\n\n### EvaluationPlugins\n\nEvaluationPlugins allow you to hook into the validation process for various\npurposes. There are hooks for before an after schema evaluation and before and\nafter keyword evaluation. (See the API section for the full interface) The\nfollowing is a simple example to record all the schema locations that were\nevaluated. This could be used as part of a solution for determining test\ncoverage for a schema.\n\n```JavaScript\nimport { registerSchema, validate } from \"@hyperjump/json-schema/draft-2020-12\";\nimport { BASIC } from \"@hyperjump/json-schema/experimental.js\";\n\nclass EvaluatedKeywordsPlugin {\n  constructor() {\n    this.schemaLocations = new Set();\n  }\n\n  beforeKeyword([, schemaUri]) {\n    this.schemaLocations.add(schemaUri);\n  }\n}\n\nregisterSchema({\n  $schema: \"https://json-schema.org/draft/2020-12/schema\",\n  type: \"object\",\n  properties: {\n    foo: { type: \"number\" },\n    bar: { type: \"boolean\" }\n  },\n  required: [\"foo\"]\n}, \"https://schemas.hyperjump.io/main\");\n\nconst evaluatedKeywordPlugin = new EvaluatedKeywordsPlugin();\n\nawait validate(\"https://schemas.hyperjump.io/main\", { foo: 42 }, {\n  outputFormat: BASIC,\n  plugins: [evaluatedKeywordPlugin]\n});\n\nconsole.log(evaluatedKeywordPlugin.schemaLocations);\n// Set(4) {\n//   'https://schemas.hyperjump.io/main#/type',\n//   'https://schemas.hyperjump.io/main#/properties',\n//   'https://schemas.hyperjump.io/main#/properties/foo/type',\n//   'https://schemas.hyperjump.io/main#/required'\n// }\n\n// NOTE: #/properties/bar is not in the list because the instance doesn't include that property.\n```\n\n### API\n\nThese are available from the `@hyperjump/json-schema/experimental` export.\n\n* **addKeyword**: (keywordHandler: Keyword) =\u003e void\n\n    Define a keyword for use in a vocabulary.\n\n    * **Keyword**: object\n      * id: string\n\n          A URI that uniquely identifies the keyword. It should use a domain you\n          own to avoid conflict with keywords defined by others.\n      * compile: (schema: Browser, ast: AST, parentSchema: Browser) =\u003e Promise\\\u003cany\u003e\n\n          This function takes the keyword value, does whatever preprocessing it\n          can on it without an instance, and returns the result. The returned\n          value will be passed to the `interpret` function. The `ast` parameter\n          is needed for compiling sub-schemas. The `parentSchema` parameter is\n          primarily useful for looking up the value of an adjacent keyword that\n          might effect this one.\n      * interpret: (compiledKeywordValue: any, instance: JsonNode, context: ValidationContext) =\u003e boolean\n\n          This function takes the value returned by the `compile` function and\n          the instance value that is being validated and returns whether the\n          value is valid or not. The other parameters are only needed for\n          validating sub-schemas.\n      * simpleApplicator?: boolean\n\n          Some applicator keywords just apply schemas and don't do any\n          validation of its own. In these cases, it isn't helpful to include\n          them in BASIC output. This flag is used to trim those nodes from the\n          output.\n      * annotation?: (compiledKeywordValue: any) =\u003e any | undefined\n\n          If the keyword is an annotation, it will need to implement this\n          function to return the annotation.\n      * plugin?: EvaluationPlugin\n\n          If the keyword needs to track state during the evaluation process, you\n          can include an EvaluationPlugin that will get added only when this\n          keyword is present in the schema.\n\n    * **ValidationContext**: object\n      * ast: AST\n      * plugins: EvaluationPlugins[]\n* **defineVocabulary**: (id: string, keywords: { [keyword: string]: string }) =\u003e void\n\n    Define a vocabulary that maps keyword name to keyword URIs defined using\n    `addKeyword`.\n* **getKeywordId**: (keywordName: string, dialectId: string) =\u003e string\n\n    Get the identifier for a keyword by its name.\n* **getKeyword**: (keywordId: string) =\u003e Keyword\n\n    Get a keyword object by its URI. This is useful for building non-validation\n    tooling.\n* **getKeywordByName**: (keywordName: string, dialectId: string) =\u003e Keyword\n\n    Get a keyword object by its name. This is useful for building non-validation\n    tooling.\n* **getKeywordName**: (dialectId: string, keywordId: string) =\u003e string\n\n    Determine a keyword's name given its URI a dialect URI. This is useful when\n    defining a keyword that depends on the value of another keyword (such as how\n    `contains` depends on `minContains` and `maxContains`).\n* **loadDialect**: (dialectId: string, dialect: { [vocabularyId: string] }, allowUnknownKeywords: boolean = false) =\u003e void\n\n    Define a dialect. In most cases, dialects are loaded automatically from the\n    `$vocabulary` keyword in the meta-schema. The only time you would need to\n    load a dialect manually is if you're creating a distinct version of JSON\n    Schema rather than creating a dialect of an existing version of JSON Schema.\n* **unloadDialect**: (dialectId: string) =\u003e void\n\n    Remove a dialect. You shouldn't need to use this function. It's called for\n    you when you call `unregisterSchema`.\n* **Validation**: Keyword\n\n    A Keyword object that represents a \"validate\" operation. You would use this\n    for compiling and evaluating sub-schemas when defining a custom keyword.\n        \n* **getSchema**: (uri: string, browser?: Browser) =\u003e Promise\\\u003cBrowser\u003e\n\n    Get a schema by it's URI taking the local schema registry into account.\n* **buildSchemaDocument**: (schema: SchemaObject | boolean, retrievalUri?: string, contextDialectId?: string) =\u003e SchemaDocument\n\n    Build a SchemaDocument from a JSON-compatible value. You might use this if\n    you're creating a custom media type plugin, such as supporting JSON Schemas\n    in YAML.\n* **canonicalUri**: (schema: Browser) =\u003e string\n\n    Returns a URI for the schema.\n* **toSchema**: (schema: Browser, options: ToSchemaOptions) =\u003e object\n\n    Get a raw schema from a Schema Document.\n\n    * **ToSchemaOptions**: object\n\n        * contextDialectId: string (default: \"\") -- If the dialect of the schema\n          matches this value, the `$schema` keyword will be omitted.\n        * includeDialect: \"auto\" | \"always\" | \"never\" (default: \"auto\") -- If\n          \"auto\", `$schema` will only be included if it differs from\n          `contextDialectId`.\n        * contextUri: string (default: \"\") -- `$id`s will be relative to this\n          URI.\n        * includeEmbedded: boolean (default: true) -- If false, embedded schemas\n          will be unbundled from the schema.\n* **compile**: (schema: Browser) =\u003e Promise\\\u003cCompiledSchema\u003e\n\n    Return a compiled schema. This is useful if you're creating tooling for\n    something other than validation.\n* **interpret**: (schema: CompiledSchema, instance: JsonNode, outputFormat: OutputFormat = BASIC) =\u003e OutputUnit\n\n    A curried function for validating an instance against a compiled schema.\n    This can be useful for creating custom output formats.\n\n* **OutputFormat**: **FLAG** | **BASIC**\n\n    In addition to the `FLAG` output format in the Stable API, the Experimental\n    API includes support for the `BASIC` format as specified in the 2019-09\n    specification (with some minor customizations). This implementation doesn't\n    include annotations or human readable error messages. The output can be\n    processed to create human readable error messages as needed.\n\n* **EvaluationPlugin**: object\n    * beforeSchema?(url: string, instance: JsonNode, context: Context): void\n    * beforeKeyword?(keywordNode: CompiledSchemaNode, instance: JsonNode, context: Context, schemaContext: Context, keyword: Keyword): void\n    * afterKeyword?(keywordNode: CompiledSchemaNode, instance: JsonNode, context: Context, valid: boolean, schemaContext: Context, keyword: Keyword): void\n    * afterSchema?(url: string, instance: JsonNode, context: Context, valid: boolean): void\n\n## Instance API (experimental)\n\nThese functions are available from the\n`@hyperjump/json-schema/instance/experimental` export.\n\nThis library uses JsonNode objects to represent instances. You'll work with\nthese objects if you create a custom keyword.\n\nThis API uses generators to iterate over arrays and objects. If you like using\nhigher order functions like `map`/`filter`/`reduce`, see\n[`@hyperjump/pact`](https://github.com/hyperjump-io/pact) for utilities for\nworking with generators and async generators.\n\n* **fromJs**: (value: any, uri?: string) =\u003e JsonNode\n\n    Construct a JsonNode from a JavaScript value.\n* **cons**: (baseUri: string, pointer: string, value: any, type: string, children: JsonNode[], parent?: JsonNode) =\u003e JsonNode\n\n    Construct a JsonNode. This is used internally. You probably want `fromJs`\n    instead.\n* **get**: (url: string, instance: JsonNode) =\u003e JsonNode\n\n    Apply a same-resource reference to a JsonNode.\n* **uri**: (instance: JsonNode) =\u003e string\n\n    Returns a URI for the value the JsonNode represents.\n* **value**: (instance: JsonNode) =\u003e any\n\n    Returns the value the JsonNode represents.\n* **has**: (key: string, instance: JsonNode) =\u003e boolean\n\n    Returns whether or not \"key\" is a property name in a JsonNode that\n    represents an object.\n* **typeOf**: (instance: JsonNode) =\u003e string\n\n    The JSON type of the JsonNode. In addition to the standard JSON types,\n    there's also the `property` type that indicates a property name/value pair\n    in an object.\n* **step**: (key: string, instance: JsonNode) =\u003e JsonType\n\n    Similar to indexing into a object or array using the `[]` operator.\n* **iter**: (instance: JsonNode) =\u003e Generator\\\u003cJsonNode\u003e\n\n    Iterate over the items in the array that the JsonNode represents.\n* **entries**: (instance: JsonNode) =\u003e Generator\\\u003c[JsonNode, JsonNode]\u003e\n\n    Similar to `Object.entries`, but yields JsonNodes for keys and values.\n* **values**: (instance: JsonNode) =\u003e Generator\\\u003cJsonNode\u003e\n\n    Similar to `Object.values`, but yields JsonNodes for values.\n* **keys**: (instance: JsonNode) =\u003e Generator\\\u003cJsonNode\u003e\n\n    Similar to `Object.keys`, but yields JsonNodes for keys.\n* **length**: (instance: JsonNode) =\u003e number\n\n    Similar to `Array.prototype.length`.\n\n## Annotations (experimental)\nJSON Schema is for annotating JSON instances as well as validating them. This\nmodule provides utilities for working with JSON documents annotated with JSON\nSchema.\n\n### Usage\nAn annotated JSON document is represented as a\n(JsonNode)[#instance-api-experimental] AST. You can use this AST to traverse\nthe data structure and get annotations for the values it represents.\n\n```javascript\nimport { registerSchema } from \"@hyperjump/json-schema/draft/2020-12\";\nimport { annotate } from \"@hyperjump/json-schema/annotations/experimental\";\nimport * as AnnotatedInstance from \"@hyperjump/json-schema/annotated-instance/experimental\";\n\n\nconst schemaId = \"https://example.com/foo\";\nconst dialectId = \"https://json-schema.org/draft/2020-12/schema\";\n\nregisterSchema({\n  \"$schema\": dialectId,\n\n  \"title\": \"Person\",\n  \"unknown\": \"foo\",\n\n  \"type\": \"object\",\n  \"properties\": {\n    \"name\": {\n      \"$ref\": \"#/$defs/name\",\n      \"deprecated\": true\n    },\n    \"givenName\": {\n      \"$ref\": \"#/$defs/name\",\n      \"title\": \"Given Name\"\n    },\n    \"familyName\": {\n      \"$ref\": \"#/$defs/name\",\n      \"title\": \"Family Name\"\n    }\n  },\n\n  \"$defs\": {\n    \"name\": {\n      \"type\": \"string\",\n      \"title\": \"Name\"\n    }\n  }\n}, schemaId);\n\nconst instance = await annotate(schemaId, {\n  name: \"Jason Desrosiers\",\n  givenName: \"Jason\",\n  familyName: \"Desrosiers\"\n});\n\n// Get the title of the instance\nconst titles = AnnotatedInstance.annotation(instance, \"title\", dialectId); // =\u003e [\"Person\"]\n\n// Unknown keywords are collected as annotations\nconst unknowns = AnnotatedInstance.annotation(instance, \"unknown\", dialectId); // =\u003e [\"foo\"]\n\n// The type keyword doesn't produce annotations\nconst types = AnnotatedInstance.annotation(instance, \"type\", dialectId); // =\u003e []\n\n// Get the title of each of the properties in the object\nfor (const [propertyNameNode, propertyInstance] of AnnotatedInstance.entries(instance)) {\n  const propertyName = AnnotatedInstance.value(propertyName);\n  console.log(propertyName, AnnotatedInstance.annotation(propertyInstance, \"title\", dialectId));\n}\n\n// List all locations in the instance that are deprecated\nfor (const deprecated of AnnotatedInstance.annotatedWith(instance, \"deprecated\", dialectId)) {\n  if (AnnotatedInstance.annotation(deprecated, \"deprecated\", dialectId)[0]) {\n    logger.warn(`The value at '${deprecated.pointer}' has been deprecated.`); // =\u003e (Example) \"WARN: The value at '/name' has been deprecated.\"\n  }\n}\n```\n\n### API\nThese are available from the `@hyperjump/json-schema/annotations/experimental`\nexport.\n\n* **annotate**: (schemaUri: string, instance: any, outputFormat: OutputFormat = BASIC) =\u003e Promise\\\u003cJsonNode\u003e\n\n    Annotate an instance using the given schema. The function is curried to\n    allow compiling the schema once and applying it to multiple instances. This\n    may throw an [InvalidSchemaError](#api) if there is a problem with the\n    schema or a ValidationError if the instance doesn't validate against the\n    schema.\n* **interpret**: (compiledSchema: CompiledSchema, instance: JsonNode, outputFormat: OutputFormat = BASIC) =\u003e JsonNode\n\n    Annotate a JsonNode object rather than a plain JavaScript value. This might\n    be useful when building tools on top of the annotation functionality, but\n    you probably don't need it.\n* **ValidationError**: Error \u0026 { output: OutputUnit }\n    The `output` field contains an `OutputUnit` with information about the\n    error.\n\n## AnnotatedInstance API (experimental)\nThese are available from the\n`@hyperjump/json-schema/annotated-instance/experimental` export. The\nfollowing functions are available in addition to the functions available in the\n[Instance API](#instance-api-experimental).\n\n* **annotation**: (instance: JsonNode, keyword: string, dialect?: string): any[];\n\n    Get the annotations for a keyword for the value represented by the JsonNode.\n* **annotatedWith**: (instance: JsonNode, keyword: string, dialect?: string): Generator\u003cJsonNode\u003e;\n\n    Get all JsonNodes that are annotated with the given keyword.\n* **setAnnotation**: (instance: JsonNode, keywordId: string, value: any) =\u003e JsonNode\n\n    Add an annotation to an instance. This is used internally, you probably\n    don't need it.\n\n## Contributing\n\n### Tests\n\nRun the tests\n\n```bash\nnpm test\n```\n\nRun the tests with a continuous test runner\n\n```bash\nnpm test -- --watch\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperjump-io%2Fjson-schema","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhyperjump-io%2Fjson-schema","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperjump-io%2Fjson-schema/lists"}