Skip to content

Commit 9e3b2cb

Browse files
authored
Merge pull request #271 from zcstarr/fix/nested-json-resolution
fix: This corrects the behavior for nested resolution for json schemas.
2 parents 3f8035d + 497c56f commit 9e3b2cb

File tree

5 files changed

+22
-9
lines changed

5 files changed

+22
-9
lines changed

nestedtest/test-schema.json

Whitespace-only changes.

src/default-protocol-handler-map.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { InvalidRemoteURLError, NonJsonRefError } from "./errors";
33
import { JSONSchema } from "@json-schema-tools/meta-schema";
44
import fetch from "isomorphic-fetch";
55

6-
const fetchHandler = async (uri: string): Promise<JSONSchema> => {
6+
const fetchHandler = async (uri: string, root: JSONSchema): Promise<JSONSchema> => {
77
let schemaReq;
88
try {
99
schemaReq = await fetch(uri);

src/index.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@ describe("referenceResolver", () => {
7171
expect(resolved.$ref).toBe("./src/test-schema.json");
7272
});
7373

74+
it("works with nested folders when using different root context", async () => {
75+
expect.assertions(1);
76+
const resolved = await referenceResolver
77+
.resolve("./test-schema-1.json", {
78+
"$ref": "./nestedtest/test-schema.json"
79+
}) as JSONSchemaObject;
80+
expect(resolved.$ref).toBe("./src/test-schema.json");
81+
});
82+
7483
it("errors on urls that arent real", async () => {
7584
expect.assertions(1);
7685
try {

src/index.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import ReferenceResolver, { ProtocolHandlerMap } from "./reference-resolver";
22
import * as fs from "fs";
3-
import { JSONSchema } from "@json-schema-tools/meta-schema";
3+
import { JSONSchema, JSONSchemaObject } from "@json-schema-tools/meta-schema";
44
import { InvalidRemoteURLError, NonJsonRefError } from "./errors";
55
import defaultProtocolHandlerMap from "./default-protocol-handler-map";
6+
import path from "path";
67

78
const fileExistsAndReadable = (f: string): Promise<boolean> => {
89
return new Promise((resolve) => {
@@ -19,12 +20,15 @@ const readFile = (f: string): Promise<string> => {
1920

2021
const nodeProtocolHandlerMap: ProtocolHandlerMap = {
2122
...defaultProtocolHandlerMap,
22-
"file": async (uri) => {
23-
if (await fileExistsAndReadable(uri) === true) {
24-
const fileContents = await readFile(uri);
23+
"file": async (uri,root: JSONSchema) => {
24+
let filePath = uri;
25+
const ref = (root as JSONSchemaObject).$ref;
26+
if(ref && ref !== uri && await fileExistsAndReadable(ref)) filePath = `${path.parse(ref).dir}/${uri}`;
27+
if (await fileExistsAndReadable(filePath) === true) {
28+
const fileContents = await readFile(filePath);
2529
return JSON.parse(fileContents) as JSONSchema;
2630
}
27-
}
31+
},
2832
}
2933

3034
export default new ReferenceResolver(nodeProtocolHandlerMap);

src/reference-resolver.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const isUrlLike = (s: string) => {
1111
}
1212

1313
export interface ProtocolHandlerMap {
14-
[protocol: string]: (uri: string) => Promise<JSONSchema | undefined>;
14+
[protocol: string]: (uri: string, root: JSONSchema) => Promise<JSONSchema | undefined>;
1515
};
1616

1717
export default class ReferenceResolver {
@@ -41,7 +41,7 @@ export default class ReferenceResolver {
4141
// protocol handler
4242
let relativePathSchema;
4343
try {
44-
relativePathSchema = await this.protocolHandlerMap.file(hashlessRef);
44+
relativePathSchema = await this.protocolHandlerMap.file(hashlessRef, root);
4545
} catch (e) {
4646
throw new NonJsonRefError({ $ref: ref }, e.message);
4747
}
@@ -57,7 +57,7 @@ export default class ReferenceResolver {
5757

5858
for (const protocol of Object.keys(this.protocolHandlerMap)) {
5959
if (hashlessRef.startsWith(protocol)) {
60-
const maybeSchema = await this.protocolHandlerMap[protocol](hashlessRef);
60+
const maybeSchema = await this.protocolHandlerMap[protocol](hashlessRef, root);
6161

6262
if (maybeSchema !== undefined) {
6363
let schema: JSONSchema = maybeSchema;

0 commit comments

Comments
 (0)