allof-merge
Merge schemas with allOf into a more readable composed schema free from allOf.
Features
- Safe merging of schemas combined with allOf in whole document
- Fastest implmentation - up to x3 times faster then other popular libraries
- Merged schema does not validate more or less than the original schema
- Removes almost all logical impossibilities
- Correctly merge additionalProperties, patternProperties and properties taking into account common validations
- Correctly merge items and additionalItems taking into account common validations
- Supports custom rules to merge other document types and JsonSchema versions
- Supports input with circular references (javaScript references)
- Supports $refs and circular $refs either (internal references only)
- Correctly merge of $refs with sibling content (optionally)
- Correctly merge of combinaries (anyOf, oneOf) with sibling content (optionally)
- Typescript syntax support out of the box
- No dependencies (except json-crawl), can be used in nodejs or browser
Works perfectly with specifications:
- JsonSchema
- OpenApi 3.x
- GraphApi
-
Swagger 2.x(roadmap) -
AsyncApi 2.x(roadmap) -
AsyncApi 3.x(roadmap)
Other libraries
There are some libraries that can merge schemas combined with allOf. One of the most popular is mokkabonna/json-schema-merge-allof, but it has some limitatons: Does not support circular $refs and no Typescript syntax out of the box.
External $ref
If schema contains an external $ref, you should bundle it via api-ref-bundler first.
Installation
npm install allof-merge --save
Usage
Nodejs
import { merge } from 'allof-merge'
const data = {
type: ['object', 'null'],
additionalProperties: {
type: 'string',
minLength: 5
},
allOf: [{
type: ['array', 'object'],
additionalProperties: {
type: 'string',
minLength: 10,
maxLength: 20
}
}]
}
const onMergeError = (msg) => {
throw new Error(msg)
}
const merged = merge(data, { onMergeError })
console.log(merged)
// {
// type: 'object',
// additionalProperties: {
// type: 'string',
// minLength: 10,
// maxLength: 20
// }
// }
Browsers
A browser version of allof-merge
is also available via CDN:
<script src="https://cdn.jsdelivr.net/npm/allof-merge@latest/browser/allof-merge.min.js"></script>
Reference allof-merge.min.js
in your HTML and use the global variable AllOfMerge
.
<script>
var merged = AllOfMerge.merge({ /* ... */ })
</script>
Documentation
merge(data: any, options?: MergeOptions)
Create a copy of data
with merged allOf schemas:
Merge options
interface MergeOptions {
// source document if merging only part of it
// (optional) default = data
source?: any
// custom merge rules
// (optional) default = auto select based on the input (jsonSchemaMergeRules, openapiMergeRules, graphapiMergeRules)
rules?: MergeRules
// merge $ref with sibling content
// (optional) default = false
mergeRefSibling?: boolean
// merge anyOf/oneOf with sibling content
// (optional) default = false
mergeCombinarySibling?: boolean
// Merge error hook, called on any merge conflicts
onMergeError?: (message: string, path: JsonPath, values: any[]) => void
// Ref resolve error hook, called on broken ref
onRefResolveError?: (message: string, path: JsonPath, ref: string) => void
}
Supported rules
You can find supported rules in the src/rules directory of this repository:
jsonSchemaMergeRules(version: "draft-04" | "draft-06")
openapiMergeRules(version: "3.0.x" | "3.1.x")
graphapiMergeRules
Benchmark
allof-merge x 657 ops/sec ±2.35% (90 runs sampled)
json-schema-merge-allof x 217 ops/sec ±2.03% (86 runs sampled)
Fastest is allof-merge
Check yourself:
npm run benchmark
Contributing
When contributing, keep in mind that it is an objective of allof-merge
to have no additional package dependencies.
Please run the unit tests before submitting your PR: yarn test
. Hopefully your PR includes additional unit tests to illustrate your change/modification!
License
MIT