Skip to content

Commit

Permalink
fix #67: cycle references support
Browse files Browse the repository at this point in the history
  • Loading branch information
udamir committed Dec 25, 2023
1 parent f439b10 commit a9fa954
Show file tree
Hide file tree
Showing 14 changed files with 114 additions and 37 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "allof-merge",
"version": "0.6.1",
"version": "0.6.2",
"description": "Simplify your JsonSchema by combining allOf safely.",
"module": "dist/index.mjs",
"main": "dist/index.cjs",
Expand Down Expand Up @@ -84,6 +84,6 @@
"collectCoverage": true
},
"dependencies": {
"json-crawl": "^0.4.2"
"json-crawl": "^0.5.1"
}
}
6 changes: 3 additions & 3 deletions src/merge.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { JsonPath, SyncCloneHook, isObject, syncClone } from "json-crawl"

import { AllOfRef, MergeError, MergeOptions, MergeResolver, MergeRules } from "./types"
import type { AllOfRef, MergeError, MergeOptions, MergeResolver, MergeRules } from "./types"
import { buildPointer, isAnyOfNode, isOneOfNode } from "./utils"
import { mergeCombinarySibling } from "./resolvers/combinary"
import { jsonSchemaMergeResolver } from "./resolvers"
Expand Down Expand Up @@ -68,11 +68,11 @@ export const allOfResolverHook = (options?: MergeOptions): SyncCloneHook<{}> =>

// skip if not object
if (!isObject(value) || Array.isArray(value)) {
return { value: value, exitHook }
return { exitHook }
}

// check if in current node expected allOf merge rule in rules
if (!isAllOfMergeRule(rules)) { return { value, exitHook } }
if (!isAllOfMergeRule(rules)) { return { exitHook } }

const { allOf, ...sibling } = value

Expand Down
4 changes: 2 additions & 2 deletions src/normalize.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { JsonPath, isObject } from "json-crawl"
import { type JsonPath, isObject } from "json-crawl"

import { buildPointer, isRefNode, parseRef, resolvePointer } from "./utils"
import { AllOfRef, NormalizeResponse } from "./types"
import type { AllOfRef, NormalizeResponse } from "./types"

export const normalizeAllOfItems = (allOfItems: any[], jsonPath: JsonPath, source: any, allOfRefs: AllOfRef[]): NormalizeResponse => {
const resolvedAllOfItems = []
Expand Down
2 changes: 1 addition & 1 deletion src/resolvers/basic.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { calculateLCM, findCombinations, isEqual, mergeValues } from "../utils"
import { getAllOfItemsMap } from "./jsonschema"
import { MergeResolver } from "../types"
import type { MergeResolver } from "../types"

export const first: MergeResolver = ([a]) => a
export const last: MergeResolver = (args) => args[args.length-1]
Expand Down
2 changes: 1 addition & 1 deletion src/resolvers/combinary.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AnyOfNode, MergeRule, OneOfNode } from "../types"
import type { AnyOfNode, MergeRule, OneOfNode } from "../types"
import { popValues } from "../utils"

export const mergeCombinarySibling = (value: AnyOfNode | OneOfNode, combinaryKey: "anyOf" | "oneOf", rule: MergeRule) => {
Expand Down
2 changes: 1 addition & 1 deletion src/resolvers/items.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { jsonSchemaMergeResolver } from "./jsonschema"
import { MergeResolver } from "../types"
import type { MergeResolver } from "../types"
import { MapArray } from "../utils"

export const itemsMergeResolver: MergeResolver = (args, ctx) => {
Expand Down
2 changes: 1 addition & 1 deletion src/resolvers/properties.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getAllOfItemsMap, jsonSchemaMergeResolver } from "./jsonschema"
import { JsonSchema, MergeResolver } from "../types"
import type { JsonSchema, MergeResolver } from "../types"
import { MapArray } from "../utils"

export const getPropertiesForMerge = (allOfItems: JsonSchema[]) => {
Expand Down
2 changes: 1 addition & 1 deletion src/rules/graphapi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { jsonSchemaMergeRules } from "./jsonschema"
import type { MergeRules } from "../types"
import * as resolvers from "../resolvers"
import { MergeRules } from "../types"

const graphSchemaMergeRules: MergeRules = jsonSchemaMergeRules("draft-06", {
"/args": () => graphSchemaMergeRules,
Expand Down
2 changes: 1 addition & 1 deletion src/rules/jsonschema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { MergeRules } from "../types"
import * as resolvers from "../resolvers"
import { MergeRules } from "../types"

export const jsonSchemaVersion = ["draft-04", "draft-06"] as const

Expand Down
2 changes: 1 addition & 1 deletion src/rules/openapi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { JsonSchemaVersion, jsonSchemaMergeRules } from "./jsonschema"
import type { MergeRules } from "../types"
import * as resolvers from "../resolvers"
import { MergeRules } from "../types"

export const openApiVersion = ["3.0.x", "3.1.x"] as const

Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { JsonPath, CrawlRules } from "json-crawl"
import type { JsonPath, CrawlRules } from "json-crawl"

export type JsonSchema = any
export type MergeRules = CrawlRules<MergeRule>
Expand Down
4 changes: 2 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { JsonPath, isObject } from "json-crawl"
import { type JsonPath, isObject } from "json-crawl"

import { AnyOfNode, OneOfNode, RefNode } from "./types"
import type { AnyOfNode, OneOfNode, RefNode } from "./types"

export class MapArray<K, V> extends Map<K, Array<V>> {
public add(key: K, value: V): this {
Expand Down
109 changes: 93 additions & 16 deletions test/merge.cycleRefs.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { merge } from "../src"

describe("cycle refs", () => {
describe("cycle $refs", () => {
it("should support cycle refs in allOf", () => {
const data = {
type: 'object',
Expand Down Expand Up @@ -28,35 +28,112 @@ describe("cycle refs", () => {
},
}

const result = merge(data)
const result: any = merge(data)

expect(result).toEqual( {
expect(result).toMatchObject( {
type: 'object',
properties: {
foo: {
description: '1-st parent',
type: 'object',
properties: {
foo: {
$ref: '#/properties/foo',
foo: result.properties.foo,
baz: result.properties.baz,
}
},
baz: {
description: '2-st parent',
type: 'object',
properties: {
foo: result.properties.foo,
baz: result.properties.baz,
}
},
},
})

// expect(result).toEqual( {
// type: 'object',
// properties: {
// foo: {
// description: '1-st parent',
// type: 'object',
// properties: {
// foo: {
// $ref: '#/properties/foo',
// },
// baz: {
// description: '2-st parent',
// type: 'object',
// properties: {
// foo: {
// $ref: '#/properties/foo',
// },
// baz: {
// $ref: '#/properties/foo/properties/baz',
// },
// }
// },

// }
// },
// baz: {
// $ref: '#/properties/foo/properties/baz',
// },
// },
// })
})

it("should support dereferenced cycle refs in allOf", () => {
const data: any = {
type: 'object',
properties: {
foo: {
allOf: [
{
description: '1-st parent',
},
{
$ref: '#',
},
baz: {
],
},
baz: {
allOf: [
{
description: '2-st parent',
type: 'object',
properties: {
foo: {
$ref: '#/properties/foo',
},
baz: {
$ref: '#/properties/foo/properties/baz',
},
}
},
{
$ref: '#',
},
],
},
},
}

data.properties.foo.allOf[1] = data
data.properties.baz.allOf[1] = data

const result: any = merge(data)

expect(result).toMatchObject({
type: 'object',
properties: {
foo: {
description: '1-st parent',
type: 'object',
properties: {
foo: result.properties.foo,
baz: result.properties.baz,
}
},
baz: {
$ref: '#/properties/foo/properties/baz',
description: '2-st parent',
type: 'object',
properties: {
foo: result.properties.foo,
baz: result.properties.baz,
}
},
},
})
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2482,10 +2482,10 @@ jsesc@^2.5.1:
resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz"
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==

json-crawl@^0.4.2:
version "0.4.2"
resolved "https://registry.yarnpkg.com/json-crawl/-/json-crawl-0.4.2.tgz#34339e4984bdf3a7f39518f1e3a0cd29ac1cc86c"
integrity sha512-MOKk9cjtpMrP4H1DmG+PtS7aFWg9OuSqxc/wpFcOE++yVnD5Bi5iKoXD6oqs+kltRwJRgZBYMozRNpQpxD/TJw==
json-crawl@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json-crawl/-/json-crawl-0.5.1.tgz#1dcd753ee1bcbebe15934f350bb577e422e5c16b"
integrity sha512-guQYl5NFDUC6XtJvlMb80rYTJ0LhY9lLlDpL6idDwSGldpGayWBzsstK7BlmULXM/WsT0jI+skiilwiRb904wA==

json-parse-even-better-errors@^2.3.0:
version "2.3.1"
Expand Down

0 comments on commit a9fa954

Please sign in to comment.