-
-
Notifications
You must be signed in to change notification settings - Fork 236
feat: dereference.preservedProperties
for preserving data during dereferencing
#369
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -123,7 +123,27 @@ function crawl<S extends object = JSONSchema, O extends ParserOptions<S> = Parse | |
circular = dereferenced.circular; | ||
// Avoid pointless mutations; breaks frozen objects to no profit | ||
if (obj[key] !== dereferenced.value) { | ||
// If we have properties we want to preserve from our derefernced schema then we need | ||
// to copy them over to our new object. | ||
const preserved: Map<string, unknown> = new Map(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: can we wrap this logic and this object allocation inside a check for if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Absolutely! |
||
if (typeof obj[key] === "object" && !Array.isArray(obj[key])) { | ||
(derefOptions?.preservedProperties || []).forEach((prop) => { | ||
if (prop in obj[key]) { | ||
preserved.set(prop, obj[key][prop]); | ||
} | ||
}); | ||
} | ||
|
||
obj[key] = dereferenced.value; | ||
|
||
// If we have data to preserve and our dereferenced object is still an object then | ||
// we need copy back our preserved data into our dereferenced schema. | ||
if (preserved.size && typeof obj[key] === "object" && !Array.isArray(obj[key])) { | ||
preserved.forEach((value, prop) => { | ||
obj[key][prop] = value; | ||
}); | ||
} | ||
|
||
derefOptions?.onDereference?.(value.$ref, obj[key], obj, key); | ||
} | ||
} else { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { describe, it } from "vitest"; | ||
import $RefParser from "../../../lib/index.js"; | ||
import pathUtils from "../../utils/path.js"; | ||
|
||
import { expect } from "vitest"; | ||
import type { Options } from "../../../lib/options"; | ||
|
||
describe("dereference.preservedProperties", () => { | ||
it("should preserve properties", async () => { | ||
const parser = new $RefParser(); | ||
const schema = pathUtils.rel("test/specs/dereference-preservedProperties/dereference-preservedProperties.yaml"); | ||
const options = { | ||
dereference: { | ||
preservedProperties: ["description"], | ||
}, | ||
} as Options; | ||
const res = await parser.dereference(schema, options); | ||
|
||
expect(res).to.deep.equal({ | ||
title: "Person", | ||
required: ["name"], | ||
type: "object", | ||
definitions: { | ||
name: { | ||
type: "string", | ||
description: "Someone's name", | ||
}, | ||
}, | ||
properties: { | ||
name: { | ||
type: "string", | ||
description: "Someone's name", | ||
}, | ||
secretName: { | ||
type: "string", | ||
description: "Someone's secret name", | ||
}, | ||
}, | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
title: Person | ||
required: | ||
- name | ||
type: object | ||
definitions: | ||
name: | ||
type: string | ||
description: Someone's name | ||
properties: | ||
name: | ||
$ref: "#/definitions/name" | ||
secretName: | ||
$ref: "#/definitions/name" | ||
# Despite "Someone's name" being the description of the referenced `name` schema our overwritten | ||
# description should be preserved instead. | ||
description: Someone's secret name |
Uh oh!
There was an error while loading. Please reload this page.