diff --git a/docs/options.md b/docs/options.md index 3efb2b04..a4e1c0fb 100644 --- a/docs/options.md +++ b/docs/options.md @@ -80,4 +80,4 @@ The `dereference` options control how JSON Schema $Ref Parser will dereference ` |:---------------------|:-------------------|:------------ |`circular`|`boolean` or `"ignore"`|Determines whether [circular `$ref` pointers](README.md#circular-refs) are handled.

If set to `false`, then a `ReferenceError` will be thrown if the schema contains any circular references.

If set to `"ignore"`, then circular references will simply be ignored. No error will be thrown, but the [`$Refs.circular`](refs.md#circular) property will still be set to `true`. |`excludedPathMatcher`|`(string) => boolean`|A function, called for each path, which can return true to stop this path and all subpaths from being dereferenced further. This is useful in schemas where some subpaths contain literal `$ref` keys that should not be dereferenced. -|`onDereference`|`(string, JSONSchemaObjectType) => void`|A function, called immediately after dereferencing, with the resolved JSON Schema value and the `$ref` being dereferenced. +|`onDereference`|`(string, JSONSchemaObjectType, JSONSchemaObjectType, string) => void`|A function, called immediately after dereferencing, with: the resolved JSON Schema value, the `$ref` being dereferenced, the object holding the dereferenced prop, the dereferenced prop name. diff --git a/lib/dereference.ts b/lib/dereference.ts index b97f12b5..ec4c6e18 100644 --- a/lib/dereference.ts +++ b/lib/dereference.ts @@ -107,7 +107,7 @@ function crawl( if (obj[key] !== dereferenced.value) { obj[key] = dereferenced.value; if (options.dereference.onDereference) { - options.dereference.onDereference(value.$ref, obj[key]); + options.dereference.onDereference(value.$ref, obj[key], obj, key); } } } else { diff --git a/lib/options.ts b/lib/options.ts index 54feb74a..86f13e62 100644 --- a/lib/options.ts +++ b/lib/options.ts @@ -79,10 +79,12 @@ interface $RefParserOptions { /** * Callback invoked during dereferencing. * - * @argument {string} path The path being dereferenced (ie. the `$ref` string). - * @argument {JSONSchemaObject} object The JSON-Schema that the `$ref` resolved to. + * @argument {string} path - The path being dereferenced (ie. the `$ref` string) + * @argument {JSONSchemaObject} value - The JSON-Schema that the `$ref` resolved to + * @argument {JSONSchemaObject} parent - The parent of the dereferenced object + * @argument {string} parentPropName - The prop name of the parent object whose value was dereferenced */ - onDereference?(path: string, value: JSONSchemaObject): void; + onDereference?(path: string, value: JSONSchemaObject, parent?: JSONSchemaObject, parentPropName?: string): void; /** * Whether a reference should resolve relative to its directory/path, or from the cwd diff --git a/test/specs/dereference-callback/dereference-callback.spec.ts b/test/specs/dereference-callback/dereference-callback.spec.ts index 5e3d74a8..4f4979c9 100644 --- a/test/specs/dereference-callback/dereference-callback.spec.ts +++ b/test/specs/dereference-callback/dereference-callback.spec.ts @@ -12,15 +12,40 @@ describe("Schema with a $ref", () => { const schema = pathUtils.rel("test/specs/dereference-callback/dereference-callback.yaml"); const options = { dereference: { - onDereference(path: any, object: any) { - calls.push({ path, object }); + onDereference(path, value, parent, parentPropName) { + calls.push({ path, value, parent, parentPropName }); }, }, } as Options; await parser.dereference(schema, options); + expect(calls).to.deep.equal([ - { path: "#/definitions/b", object: { $ref: "#/definitions/a" } }, - { path: "#/definitions/a", object: { $ref: "#/definitions/a" } }, + { + path: "#/definitions/b", + value: { $ref: "#/definitions/a" }, + parent: { + a: { + $ref: "#/definitions/a", + }, + b: { + $ref: "#/definitions/a", + }, + }, + parentPropName: "a", + }, + { + path: "#/definitions/a", + value: { $ref: "#/definitions/a" }, + parent: { + c: { + type: "string", + }, + d: { + $ref: "#/definitions/a", + }, + }, + parentPropName: "d", + }, ]); }); });