Skip to content

Commit

Permalink
add auto select for merge rules based on input
Browse files Browse the repository at this point in the history
  • Loading branch information
udamir committed Dec 25, 2023
1 parent 39302d7 commit d01d881
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 16 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
<img alt="npm" src="https://img.shields.io/npm/v/allof-merge"> <img alt="npm" src="https://img.shields.io/npm/dm/allof-merge?label=npm"> ![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/udamir/allof-merge/ci.yml)
<img alt="npm type definitions" src="https://img.shields.io/npm/types/allof-merge"> ![Coveralls branch](https://img.shields.io/coverallsCoverage/github/udamir/allof-merge) <img alt="GitHub" src="https://img.shields.io/github/license/udamir/allof-merge">

Merge schemas using allOf into a more readable composed schema free from allOf.
Merge schemas with allOf into a more readable composed schema free from allOf.

## Features
- Safe merging of schemas combined with allOf in whole JsonSchema based document
- Fastest implmentation - up to x4 times faster then other popular libraries
- 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 rules extension to merge other document types and JsonSchema versions
- 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)
Expand Down Expand Up @@ -108,7 +108,7 @@ interface MergeOptions {
source?: any

// custom merge rules
// (optional) default = jsonSchemaMergeRules("draft-06")
// (optional) default = auto select based on the input (jsonSchemaMergeRules, openapiMergeRules, graphapiMergeRules)
rules?: MergeRules

// merge $ref with sibling content
Expand All @@ -135,7 +135,7 @@ You can find supported rules in the src/rules directory of this repository:

## Benchmark
```
allof-merge x 800 ops/sec ±2.35% (90 runs sampled)
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
```
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "allof-merge",
"version": "0.6.2",
"description": "Simplify your JsonSchema by combining allOf safely.",
"version": "0.6.3",
"description": "Simplify JsonSchema/Openapi by combining allOf safely",
"module": "dist/index.mjs",
"main": "dist/index.cjs",
"browser": "dist/index.iife.js",
Expand Down
20 changes: 17 additions & 3 deletions src/merge.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
import { JsonPath, SyncCloneHook, isObject, syncClone } from "json-crawl"
import { type JsonPath, type SyncCloneHook, isObject, syncClone } from "json-crawl"

import type { AllOfRef, MergeError, MergeOptions, MergeResolver, MergeRules } from "./types"
import { graphapiMergeRules, jsonSchemaMergeRules, openApiMergeRules } from "./rules"
import { buildPointer, isAnyOfNode, isOneOfNode } from "./utils"
import { mergeCombinarySibling } from "./resolvers/combinary"
import { jsonSchemaMergeResolver } from "./resolvers"
import { normalizeAllOfItems } from "./normalize"
import { jsonSchemaMergeRules } from "./rules"
import { ErrorMessage } from "./errors"

export const selectMergeRules = (data: unknown): MergeRules => {
if (typeof data !== "object" || !data) { return jsonSchemaMergeRules() }

if ("openapi" in data && typeof data.openapi === "string" && /3.+/.test(data.openapi)) {
const version = data.openapi.startsWith("3.1") ? "3.1.x" : "3.0.x"
return openApiMergeRules(version)
}
// if ("asyncapi" in data && typeof data.asyncapi === "string" && /2.+/.test(data?.asyncapi)) return asyncApi2MergeRules
// if ("swagger" in data && typeof data.swagger === "string" && /2.+/.test(data?.swagger)) return swagger2MergeRules
if ("graphapi" in data && typeof data.graphapi === "string") return graphapiMergeRules
return jsonSchemaMergeRules()
}


export const merge = (value: any, options?: MergeOptions) => {
const rules: MergeRules = options?.rules || jsonSchemaMergeRules()
const rules: MergeRules = options?.rules ?? selectMergeRules(value)
return syncClone(value, allOfResolverHook(options), { rules })
}

Expand Down
4 changes: 2 additions & 2 deletions test/merge.graphapi.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { merge, graphapiMergeRules } from "../src"
import { graphapi, yaml } from "./helpers"
import { merge } from "../src"

describe("Build GraphApi", () => {

Expand Down Expand Up @@ -55,7 +55,7 @@ describe("Build GraphApi", () => {
}
`

const merged = merge(schema, { rules: graphapiMergeRules, mergeCombinarySibling: true, mergeRefSibling: true })
const merged = merge(schema, { mergeCombinarySibling: true, mergeRefSibling: true })

const expected = yaml`
graphapi: 0.1.2
Expand Down
6 changes: 3 additions & 3 deletions test/merge.openapi.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { merge, openApiMergeRules } from "../src"
import { merge } from "../src"
const source31x = require("./resources/openapi31x.json")
const source30x = require("./resources/openapi30x.json")

describe("merge allof in openapi schema", function () {
it("merges schema in openapi 3.0.x", () => {
const result = merge(source30x, { rules: openApiMergeRules() })
const result = merge(source30x)

expect(result).toMatchObject({
openapi: "3.0.2",
Expand Down Expand Up @@ -106,7 +106,7 @@ describe("merge allof in openapi schema", function () {
})

it("merges schema in openapi 3.1.x", () => {
const result = merge(source31x, { rules: openApiMergeRules("3.1.x") })
const result = merge(source31x)

expect(result).toMatchObject({
openapi: "3.1.0",
Expand Down

0 comments on commit d01d881

Please sign in to comment.