Skip to content
This repository was archived by the owner on Jul 13, 2023. It is now read-only.

Commit b7a1dbe

Browse files
author
Marc MacLeod
authored
feat: isRef (#5)
also includes: * chore: update scripts to 3.0.0 * docs: hide private classes from typedoc * chore: use @stoplight/json * docs: improve type names and docs * docs(readme): add basic example
1 parent 15fc3bd commit b7a1dbe

File tree

15 files changed

+1024
-660
lines changed

15 files changed

+1024
-660
lines changed

README.md

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,42 @@ yarn add @stoplight/json-ref-resolver
2727

2828
### Usage
2929

30-
All relevant types and options can be found in [src/types.ts](src/types.ts).
30+
All relevant types and options can be found in [src/types.ts](src/types.ts) or in the TSDoc.
31+
32+
#### Basic Local Resolution
33+
34+
```ts
35+
import { Resolver } from "@stoplight/json-ref-resolver";
36+
37+
const resolver = new Resolver();
38+
const resolved = await resolver.resolve({
39+
user: {
40+
$ref: "#/models/user"
41+
},
42+
models: {
43+
user: {
44+
name: "john"
45+
}
46+
}
47+
});
48+
49+
console.log(resolved.result);
50+
51+
// ==> outputs the original object, with local refs resolved and replaced
52+
//
53+
// {
54+
// user: {
55+
// name: 'json'
56+
// },
57+
// models: {
58+
// user: {
59+
// name: 'john'
60+
// }
61+
// }
62+
// }
63+
```
64+
65+
#### With Authority Readers
3166

3267
```ts
3368
import { Resolver } from "@stoplight/json-ref-resolver";

package.json

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,15 @@
55
"keywords": [
66
"json-parser",
77
"json",
8+
"jsonschema",
89
"json-schema",
10+
"json-pointer",
11+
"$ref",
912
"resolver",
1013
"openapi",
11-
"swagger"
14+
"swagger",
15+
"dereference",
16+
"resolve"
1217
],
1318
"main": "src/index.ts",
1419
"sideEffects": false,
@@ -21,15 +26,14 @@
2126
},
2227
"license": "Apache-2.0",
2328
"files": [
24-
"**/*",
25-
"!__tests__"
29+
"**/*"
2630
],
2731
"engines": {
2832
"node": ">=8.3.0"
2933
},
3034
"scripts": {
3135
"build": "sl-scripts build",
32-
"build.docs": "sl-scripts build:tsdoc",
36+
"build.docs": "sl-scripts build:typedoc",
3337
"commit": "git-cz",
3438
"lint": "sl-scripts lint",
3539
"lint.fix": "yarn lint --fix",
@@ -42,22 +46,22 @@
4246
"test.watch": "yarn test --watch"
4347
},
4448
"dependencies": {
45-
"@stoplight/fast-safe-stringify": "2.1.x",
49+
"@stoplight/json": "1.1.x",
4650
"dependency-graph": "0.7.x",
47-
"fast-memoize": "2.5.x",
48-
"immer": "1.7.x",
51+
"fast-memoize": "2.x.x",
52+
"immer": "1.x.x",
4953
"lodash": "4.x.x",
50-
"urijs": "1.19.x"
54+
"urijs": "1.x.x"
5155
},
5256
"devDependencies": {
53-
"@stoplight/scripts": "1.1.2",
57+
"@stoplight/scripts": "3.0.0",
5458
"@types/lodash": "4.x.x",
5559
"@types/urijs": "1.15.x",
5660
"benchmark": "2.x.x",
5761
"typescript": "3.1.6"
5862
},
5963
"lint-staged": {
60-
"*.ts": [
64+
"*.{ts,tsx}$": [
6165
"yarn lint.fix",
6266
"git add"
6367
]

src/__tests__/resolver.spec.ts

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import * as fs from 'fs';
22
import * as URI from 'urijs';
33

4+
import { Cache } from '../cache';
45
import { Resolver } from '../resolver';
5-
import { ResolveRunner } from '../runner';
6+
import { defaultGetRef, ResolveRunner } from '../runner';
67
import * as Types from '../types';
78
import httpMocks from './fixtures/http-mocks';
89
import resolvedResults from './fixtures/resolved';
@@ -134,8 +135,7 @@ describe('resolver', () => {
134135
word: 'world',
135136
};
136137

137-
const resolver = new Resolver();
138-
resolver.resolvePointers = false;
138+
const resolver = new Resolver({ resolvePointers: false });
139139
const resolved = await resolver.resolve(source);
140140
expect(resolved.result).toEqual(source);
141141
});
@@ -306,11 +306,11 @@ describe('resolver', () => {
306306
};
307307

308308
const resolver = new Resolver({
309+
resolveAuthorities: false,
309310
readers: {
310311
custom: reader,
311312
},
312313
});
313-
resolver.resolveAuthorities = false;
314314

315315
const resolved = await resolver.resolve(source);
316316

@@ -791,9 +791,9 @@ describe('resolver', () => {
791791
readers: {
792792
custom: reader,
793793
},
794-
authorityCacheOpts: {
794+
authorityCache: new Cache({
795795
stdTTL: 1000, // 1s cache
796-
},
796+
}),
797797
});
798798

799799
let resolved = await resolver.resolve(source);
@@ -1089,6 +1089,63 @@ describe('resolver', () => {
10891089
expect(resolved.result.inner).toEqual('hello2');
10901090
});
10911091

1092+
/**
1093+
* This allows the end user to completely customize which properties are resolved.
1094+
*/
1095+
test('should support `getRef` hook', async () => {
1096+
const source = {
1097+
inner: {
1098+
randomProp: '#/foo',
1099+
},
1100+
foo: 'hello1',
1101+
};
1102+
1103+
const resolver = new Resolver({
1104+
getRef(_key, val) {
1105+
if (typeof val === 'string' && val.startsWith('#/')) return val;
1106+
return;
1107+
},
1108+
});
1109+
1110+
const resolved = await resolver.resolve(source);
1111+
expect(resolved.result.inner).toEqual({
1112+
randomProp: 'hello1',
1113+
});
1114+
});
1115+
1116+
/**
1117+
* This version preserves the original $ref handling, combined with our custom getRef logic.
1118+
*/
1119+
test('should support `getRef` hook combined with defaultGetRef', async () => {
1120+
const source = {
1121+
inner: {
1122+
randomProp: '#/foo',
1123+
},
1124+
inner2: {
1125+
$ref: '#/bar',
1126+
},
1127+
foo: 'hello1',
1128+
bar: 'hello2',
1129+
};
1130+
1131+
const resolver = new Resolver({
1132+
getRef(key, val) {
1133+
if (typeof val === 'string' && val.startsWith('#/')) return val;
1134+
return defaultGetRef(key, val);
1135+
},
1136+
});
1137+
1138+
const resolved = await resolver.resolve(source);
1139+
expect(resolved.result).toEqual({
1140+
inner: {
1141+
randomProp: 'hello1',
1142+
},
1143+
inner2: 'hello2',
1144+
foo: 'hello1',
1145+
bar: 'hello2',
1146+
});
1147+
});
1148+
10921149
/**
10931150
* Allows the consumer to provide a custom parser to parse lookup results before they get
10941151
* cached and returned.

src/__tests__/utils.spec.ts

Lines changed: 0 additions & 23 deletions
This file was deleted.

src/cache.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as Types from './types';
22

3+
/** @hidden */
34
export class Cache implements Types.ICache {
45
public debug = false;
56

@@ -23,7 +24,7 @@ export class Cache implements Types.ICache {
2324
};
2425
} = {};
2526

26-
constructor(opts: Types.ICacheOptions = {}) {
27+
constructor(opts: Types.ICacheOpts = {}) {
2728
this._stdTTL = opts.stdTTL;
2829
}
2930

src/crawler.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import { pointerToPath } from '@stoplight/json';
12
import { DepGraph } from 'dependency-graph';
3+
import _get = require('lodash/get');
24

3-
import { getValue } from './json';
45
import * as Types from './types';
56
import * as Utils from './utils';
67

7-
export class ResolveCrawler implements Types.IResolveCrawler {
8+
/** @hidden */
9+
export class ResolveCrawler implements Types.ICrawler {
810
public readonly authorityResolvers: Array<Promise<Types.IAuthorityLookupResult>> = [];
911

1012
// jsonPointer = the jsonPointer the runner was originally called with
@@ -95,7 +97,7 @@ export class ResolveCrawler implements Types.IResolveCrawler {
9597
if (Utils.uriIsJSONPointer(ref)) {
9698
if (this._runner.resolvePointers) {
9799
const targetPointer = Utils.uriToJSONPointer(ref);
98-
const targetPath = Utils.jsonPointerToPath(targetPointer);
100+
const targetPath = pointerToPath(targetPointer);
99101

100102
/**
101103
* Protects against circular references back to something higher up in the tree
@@ -152,7 +154,7 @@ export class ResolveCrawler implements Types.IResolveCrawler {
152154
pointerStack.push(targetPointer);
153155

154156
// if we are partially resolving
155-
this.computeGraph(getValue(this._runner.source, targetPath), targetPath, targetPointer, pointerStack);
157+
this.computeGraph(_get(this._runner.source, targetPath), targetPath, targetPointer, pointerStack);
156158

157159
pointerStack.pop();
158160
}

src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
export * from './resolver';
2+
3+
import { defaultGetRef } from './runner';
4+
export { defaultGetRef };

src/json.ts

Lines changed: 0 additions & 84 deletions
This file was deleted.

0 commit comments

Comments
 (0)