Skip to content

Commit

Permalink
fix: all systems go
Browse files Browse the repository at this point in the history
  • Loading branch information
BelfordZ committed Jun 30, 2020
1 parent f86b715 commit 6d051ff
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 77 deletions.
6 changes: 3 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
test:
<<: *defaults
docker:
- image: circleci/node:10
- image: circleci/node:latest
steps:
- checkout
- restore_cache: *restore-deps-cache
Expand All @@ -42,7 +42,7 @@ jobs:
build:
<<: *defaults
docker:
- image: circleci/node:10
- image: circleci/node:latest
steps:
- checkout
- restore_cache: *restore-deps-cache
Expand All @@ -53,7 +53,7 @@ jobs:
release:
<<: *defaults
docker:
- image: circleci/node:10
- image: circleci/node:latest
steps:
- checkout
- restore_cache: *restore-deps-cache
Expand Down
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
},
"dependencies": {
"@json-schema-spec/json-pointer": "^0.1.2",
"@json-schema-tools/traverse": "^1.1.0",
"@json-schema-tools/traverse": "^1.2.0",
"node-fetch": "^2.6.0"
}
}
14 changes: 7 additions & 7 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe("Dereferencer", () => {
});
const dereffed = await dereferencer.resolve();
const props = dereffed.properties as ObjectWji6VXSR;
expect(props.bar).toStrictEqual(props.foo);
expect(props.bar).toBe(props.foo);
expect(props.jsonSchemaMetaSchema.type).toBeDefined();
expect(props.fromFile.type).toBeDefined();
});
Expand All @@ -36,9 +36,9 @@ describe("Dereferencer", () => {
});
const dereffed = await dereferencer.resolve();
const props = dereffed.properties as ObjectWji6VXSR;
expect(props.bar).toStrictEqual(props.foo);
expect(props.baz).toStrictEqual(props.foo);
expect(props.baz).toStrictEqual(props.bar);
expect(props.bar).toBe(props.foo);
expect(props.baz).toBe(props.foo);
expect(props.baz).toBe(props.bar);
});

it("order doesnt matter", async () => {
Expand All @@ -52,9 +52,9 @@ describe("Dereferencer", () => {
});
const dereffed = await dereferencer.resolve();
const props = dereffed.properties as ObjectWji6VXSR;
expect(props.bar).toStrictEqual(props.foo);
expect(props.baz).toStrictEqual(props.foo);
expect(props.baz).toStrictEqual(props.bar);
expect(props.bar).toBe(props.foo);
expect(props.baz).toBe(props.foo);
expect(props.baz).toBe(props.bar);
expect(props.baz.type).toBe("string");
});

Expand Down
75 changes: 14 additions & 61 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ export class InvalidFileSystemPathError extends Error {
export class Dereferencer {

public refs: string[];
private refCache: { [k: string]: CoreSchemaMetaSchema } = {};
private schema: CoreSchemaMetaSchema;

constructor(schema: CoreSchemaMetaSchema, private options?: DereferencerOptions) {
Expand All @@ -172,22 +173,24 @@ export class Dereferencer {
*
*/
public async resolve(): Promise<CoreSchemaMetaSchema> {
const fetchedRefs = await Promise.all(this.refs.map((ref) => {
return this.fetchRef(ref).then((fetchedRef) => ({ [ref]: fetchedRef }));
}));

let refMap: { [s: string]: CoreSchemaMetaSchema } = {};
fetchedRefs.forEach((r) => { refMap = { ...refMap, ...r }; });
const refMap: { [s: string]: CoreSchemaMetaSchema } = {};
for (const ref of this.refs) {
refMap[ref] = await this.fetchRef(ref);
}

return traverse(this.schema, (s) => {
if (s.$ref !== undefined) {
return refMap[s.$ref];
}
return s;
});
}, { mutable: true });
}

private async fetchRef(ref: string): Promise<CoreSchemaMetaSchema> {
if (this.refCache[ref] !== undefined) {
return this.refCache[ref];
}

if (ref[0] === "#") {
const withoutHash = ref.replace("#", "");
try {
Expand All @@ -198,6 +201,7 @@ export class Dereferencer {
return this.fetchRef(reffedSchema.$ref);
}

this.refCache[ref] = reffedSchema;
return Promise.resolve(reffedSchema);
} catch (e) {
throw new InvalidJsonPointerRefError({ $ref: ref });
Expand All @@ -219,6 +223,7 @@ export class Dereferencer {
// (todo when we have validator)

// return it
this.refCache[ref] = reffedSchema;
return reffedSchema;
} else if (["$", ".", "/"].indexOf(ref[0]) !== -1) {
// there is good reason to assume this was intended to be a file path, but it was
Expand All @@ -232,6 +237,8 @@ export class Dereferencer {
const fetchResult = await fetch(ref);
try {
const reffedSchema = await fetchResult.json();

this.refCache[ref] = reffedSchema;
return reffedSchema;
} catch (e) {
throw new NonJsonRefError({ $ref: ref }, await fetchResult.text());
Expand All @@ -256,60 +263,6 @@ export class Dereferencer {
});
return refs;
}

/**
* the guts
*
* At some point soon this should mainly just apply middleware that is available.
*
*/
private async applyDeref(schema: CoreSchemaMetaSchema): Promise<CoreSchemaMetaSchema> {
if (schema.$ref === undefined) { return schema; }
if (typeof schema.$ref !== "string") { throw new NonStringRefError(schema); }

// handle internal reference
if (schema.$ref[0] === "#") {
const withoutHash = schema.$ref.replace("#", "");
try {
const pointer = Ptr.parse(withoutHash);
const reffedSchema = pointer.eval(this.schema);
return reffedSchema;
} catch (e) {
throw new InvalidJsonPointerRefError(schema);
}
}

// handle file references
if (await fileExistsAndReadable(schema.$ref) === true) {
const fileContents = await readFile(schema.$ref);
let reffedSchema;
try {
reffedSchema = JSON.parse(fileContents);
} catch (e) {
throw new NonJsonRefError(schema, fileContents);
}

// throw if not valid json schema
// (todo when we have validator)

// return it
return reffedSchema;
}

// handle http/https uri references
// this forms the base case. We use node-fetch (or injected fetch lib) and let r rip
try {
const fetchResult = await fetch(schema.$ref);
try {
const reffedSchema = await fetchResult.json();
return reffedSchema;
} catch (e) {
throw new NonJsonRefError(schema, await fetchResult.text());
}
} catch (e) { /* noop */ }

return schema;
}
}

export default Dereferencer;

0 comments on commit 6d051ff

Please sign in to comment.