diff --git a/README.md b/README.md
index d090bc76..d7164c34 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
+NOTE: This is a temporary fork of [APIDevTools/json-schema-ref-parser](https://github.com/APIDevTools/json-schema-ref-parser). Context [here](https://github.com/bcherny/json-schema-to-typescript/issues/469).
+
JSON Schema $Ref Parser
============================
#### Parse, Resolve, and Dereference JSON Schema $ref pointers
diff --git a/docs/options.md b/docs/options.md
index 8cfc4cae..3efb2b04 100644
--- a/docs/options.md
+++ b/docs/options.md
@@ -31,7 +31,9 @@ $RefParser.dereference("my-schema.yaml", {
dereference: {
circular: false, // Don't allow circular $refs
excludedPathMatcher: (path) => // Skip dereferencing content under any 'example' key
- path.includes("/example/")
+ path.includes("/example/"),
+ onDereference: (path, value) => // Callback invoked during dereferencing
+ console.log(path, value)
}
});
```
@@ -77,4 +79,5 @@ The `dereference` options control how JSON Schema $Ref Parser will dereference `
|Option(s) |Type |Description
|:---------------------|:-------------------|:------------
|`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.
+|`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.
diff --git a/lib/dereference.js b/lib/dereference.js
index f6b2b203..cb9e3833 100644
--- a/lib/dereference.js
+++ b/lib/dereference.js
@@ -71,6 +71,9 @@ function crawl (obj, path, pathFromRoot, parents, processedObjects, dereferenced
// Avoid pointless mutations; breaks frozen objects to no profit
if (obj[key] !== dereferenced.value) {
obj[key] = dereferenced.value;
+ if (options.dereference.onDereference) {
+ options.dereference.onDereference(value.$ref, obj[key])
+ }
}
}
else {
diff --git a/lib/index.d.ts b/lib/index.d.ts
index 547f27fe..2590fe82 100644
--- a/lib/index.d.ts
+++ b/lib/index.d.ts
@@ -1,4 +1,4 @@
-import { JSONSchema4, JSONSchema4Type, JSONSchema6, JSONSchema6Type, JSONSchema7, JSONSchema7Type } from "json-schema";
+import { JSONSchema4, JSONSchema4Object, JSONSchema4Type, JSONSchema6, JSONSchema6Object, JSONSchema6Type, JSONSchema7, JSONSchema7Object, JSONSchema7Type } from "json-schema";
export = $RefParser;
@@ -174,6 +174,7 @@ declare class $RefParser {
declare namespace $RefParser {
export type JSONSchema = JSONSchema4 | JSONSchema6 | JSONSchema7;
+ export type JSONSchemaObject = JSONSchema4Object | JSONSchema6Object | JSONSchema7Object;
export type SchemaCallback = (err: Error | null, schema?: JSONSchema) => any;
export type $RefsCallback = (err: Error | null, $refs?: $Refs) => any;
@@ -238,6 +239,14 @@ declare namespace $RefParser {
* subpaths contain literal $ref keys that should not be dereferenced.
*/
excludedPathMatcher?(path: string): boolean;
+
+ /**
+ * 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.
+ */
+ onDereference(path: string, value: JSONSchemaObject): void;
};
}
diff --git a/package.json b/package.json
index 4cea85a6..4c6457da 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "name": "@apidevtools/json-schema-ref-parser",
+ "name": "@bcherny/json-schema-ref-parser",
"version": "0.0.0-dev",
"description": "Parse, Resolve, and Dereference JSON Schema $ref pointers",
"keywords": [
diff --git a/test/specs/dereference-callback/dereference-callback.spec.js b/test/specs/dereference-callback/dereference-callback.spec.js
new file mode 100644
index 00000000..074fd687
--- /dev/null
+++ b/test/specs/dereference-callback/dereference-callback.spec.js
@@ -0,0 +1,26 @@
+"use strict";
+
+const { expect } = require("chai");
+const $RefParser = require("../../..");
+const path = require("../../utils/path");
+
+describe("Schema with a $ref", () => {
+ it("should call onDereference", async () => {
+ let parser = new $RefParser();
+ const calls = [];
+ const schema = await parser.dereference(
+ path.rel("specs/dereference-callback/dereference-callback.yaml"),
+ {
+ dereference: {
+ onDereference(path, object) {
+ calls.push({ path, object });
+ },
+ },
+ }
+ );
+ expect(calls).to.deep.equal([
+ { path: "#/definitions/b", object: { $ref: "#/definitions/a" } },
+ { path: "#/definitions/a", object: { $ref: "#/definitions/a" } },
+ ]);
+ });
+});
diff --git a/test/specs/dereference-callback/dereference-callback.yaml b/test/specs/dereference-callback/dereference-callback.yaml
new file mode 100644
index 00000000..f9c40dd9
--- /dev/null
+++ b/test/specs/dereference-callback/dereference-callback.yaml
@@ -0,0 +1,12 @@
+title: test
+type: object
+definitions:
+ a:
+ $ref: "#/definitions/b"
+ b:
+ $ref: "#/definitions/a"
+properties:
+ c:
+ type: string
+ d:
+ $ref: "#/definitions/a"