Skip to content

Commit 82336ed

Browse files
Boris Chernyphilsturgeon
authored andcommitted
feat: add support for options.dereference.onDereference
1 parent 138f648 commit 82336ed

File tree

5 files changed

+56
-3
lines changed

5 files changed

+56
-3
lines changed

docs/options.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ $RefParser.dereference("my-schema.yaml", {
3131
dereference: {
3232
circular: false, // Don't allow circular $refs
3333
excludedPathMatcher: (path) => // Skip dereferencing content under any 'example' key
34-
path.includes("/example/")
34+
path.includes("/example/"),
35+
onDereference: (path, value) => // Callback invoked during dereferencing
36+
console.log(path, value)
3537
}
3638
});
3739
```
@@ -77,4 +79,5 @@ The `dereference` options control how JSON Schema $Ref Parser will dereference `
7779
|Option(s) |Type |Description
7880
|:---------------------|:-------------------|:------------
7981
|`circular`|`boolean` or `"ignore"`|Determines whether [circular `$ref` pointers](README.md#circular-refs) are handled.<br><br>If set to `false`, then a `ReferenceError` will be thrown if the schema contains any circular references.<br><br> 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`.
80-
|`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.
82+
|`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.
83+
|`onDereference`|`(string, JSONSchemaObjectType) => void`|A function, called immediately after dereferencing, with the resolved JSON Schema value and the `$ref` being dereferenced.

lib/dereference.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ function crawl (obj, path, pathFromRoot, parents, processedObjects, dereferenced
7171
// Avoid pointless mutations; breaks frozen objects to no profit
7272
if (obj[key] !== dereferenced.value) {
7373
obj[key] = dereferenced.value;
74+
if (options.dereference.onDereference) {
75+
options.dereference.onDereference(value.$ref, obj[key])
76+
}
7477
}
7578
}
7679
else {

lib/index.d.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { JSONSchema4, JSONSchema4Type, JSONSchema6, JSONSchema6Type, JSONSchema7, JSONSchema7Type } from "json-schema";
1+
import { JSONSchema4, JSONSchema4Object, JSONSchema4Type, JSONSchema6, JSONSchema6Object, JSONSchema6Type, JSONSchema7, JSONSchema7Object, JSONSchema7Type } from "json-schema";
22

33
export = $RefParser;
44

@@ -174,6 +174,7 @@ declare class $RefParser {
174174
declare namespace $RefParser {
175175

176176
export type JSONSchema = JSONSchema4 | JSONSchema6 | JSONSchema7;
177+
export type JSONSchemaObject = JSONSchema4Object | JSONSchema6Object | JSONSchema7Object;
177178
export type SchemaCallback = (err: Error | null, schema?: JSONSchema) => any;
178179
export type $RefsCallback = (err: Error | null, $refs?: $Refs) => any;
179180

@@ -238,6 +239,14 @@ declare namespace $RefParser {
238239
* subpaths contain literal $ref keys that should not be dereferenced.
239240
*/
240241
excludedPathMatcher?(path: string): boolean;
242+
243+
/**
244+
* Callback invoked during dereferencing.
245+
*
246+
* @argument {string} path The path being dereferenced (ie. the `$ref` string).
247+
* @argument {JSONSchemaObject} object The JSON-Schema that the `$ref` resolved to.
248+
*/
249+
onDereference(path: string, value: JSONSchemaObject): void;
241250
};
242251
}
243252

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"use strict";
2+
3+
const { expect } = require("chai");
4+
const $RefParser = require("../../..");
5+
const path = require("../../utils/path");
6+
7+
describe("Schema with a $ref", () => {
8+
it("should call onDereference", async () => {
9+
let parser = new $RefParser();
10+
const calls = [];
11+
const schema = await parser.dereference(
12+
path.rel("specs/dereference-callback/dereference-callback.yaml"),
13+
{
14+
dereference: {
15+
onDereference(path, object) {
16+
calls.push({ path, object });
17+
},
18+
},
19+
}
20+
);
21+
expect(calls).to.deep.equal([
22+
{ path: "#/definitions/b", object: { $ref: "#/definitions/a" } },
23+
{ path: "#/definitions/a", object: { $ref: "#/definitions/a" } },
24+
]);
25+
});
26+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
title: test
2+
type: object
3+
definitions:
4+
a:
5+
$ref: "#/definitions/b"
6+
b:
7+
$ref: "#/definitions/a"
8+
properties:
9+
c:
10+
type: string
11+
d:
12+
$ref: "#/definitions/a"

0 commit comments

Comments
 (0)