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

Commit e615c6d

Browse files
authored
fix: do not ignore empty $refs (#212)
* fix: do not ignore empty $refs * test: node-carbon outputs slightly different error message
1 parent 2ef8b10 commit e615c6d

File tree

5 files changed

+61
-7
lines changed

5 files changed

+61
-7
lines changed

src/__tests__/resolver.spec.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,43 @@ describe('resolver', () => {
181181
});
182182
});
183183

184+
test('should attempt to resolve whitespace-only $refs', async () => {
185+
const source = {
186+
empty: {
187+
$ref: '',
188+
},
189+
whitespace: {
190+
$ref: ' ',
191+
},
192+
};
193+
194+
const resolver = new Resolver({
195+
resolvers: {
196+
file: new FileReader(),
197+
},
198+
});
199+
const result = await resolver.resolve(source);
200+
201+
expect(result.errors).toStrictEqual([
202+
{
203+
code: 'RESOLVE_URI',
204+
message: expect.stringMatching(/^Error: ENOENT: no such file or directory, open/),
205+
path: ['empty'],
206+
pointerStack: [],
207+
uriStack: [],
208+
uri: expect.any(Object),
209+
},
210+
{
211+
code: 'RESOLVE_URI',
212+
message: "Error: ENOENT: no such file or directory, open ' '",
213+
path: ['whitespace'],
214+
pointerStack: [],
215+
uriStack: [],
216+
uri: expect.any(Object),
217+
},
218+
]);
219+
});
220+
184221
test('should respect immutability rules', async () => {
185222
const source = {
186223
hello: {

src/crawler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export class ResolveCrawler implements Types.ICrawler {
4242
* "$ref": "#/hi"
4343
* }
4444
*/
45-
if (ref) {
45+
if (ref !== undefined) {
4646
this._resolveRef({
4747
ref,
4848
val: target,
@@ -69,7 +69,7 @@ export class ResolveCrawler implements Types.ICrawler {
6969
parentPath.push(key);
7070

7171
// if this value a ref, resolve and continue on to the next property
72-
if (ref) {
72+
if (ref !== undefined) {
7373
this._resolveRef({
7474
ref,
7575
val,

src/runner.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import produce, { original } from 'immer';
55
import get = require('lodash.get');
66
import set = require('lodash.set');
77
import * as URI from 'urijs';
8+
import { ExtendedURI } from './uri';
89

910
import { Cache } from './cache';
1011
import { ResolveCrawler } from './crawler';
@@ -319,9 +320,9 @@ export class ResolveRunner implements Types.IResolveRunner {
319320
public computeRef = (opts: Types.IComputeRefOpts): URI | void => {
320321
const refStr = this.getRef(opts.key, opts.val);
321322

322-
if (!refStr) return;
323+
if (refStr === undefined) return;
323324

324-
let ref = new URI(refStr);
325+
let ref: URI = new ExtendedURI(refStr);
325326

326327
// Does ref only have a fragment
327328
if (refStr[0] !== '#') {

src/uri.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import * as BaseURI from 'urijs';
2+
3+
export class ExtendedURI extends BaseURI {
4+
constructor(private readonly _value: string) {
5+
super(_value);
6+
}
7+
8+
public get length() {
9+
return this._value.length;
10+
}
11+
}

src/utils.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as URI from 'urijs';
2+
import { ExtendedURI } from './uri';
23

34
const replace = (str: string, find: string, repl: string): string => {
45
// modified from http://jsperf.com/javascript-replace-all/10
@@ -33,11 +34,15 @@ export const addToJSONPointer = (pointer: string, part: string): string => {
3334
};
3435

3536
/** @hidden */
36-
export const uriToJSONPointer = (uri: URI): string => {
37+
export const uriToJSONPointer = (uri: URI | ExtendedURI): string => {
38+
if ('length' in uri && uri.length === 0) {
39+
return '';
40+
}
41+
3742
return uri.fragment() !== '' ? `#${uri.fragment()}` : uri.href() === '' ? '#' : '';
3843
};
3944

4045
/** @hidden */
41-
export const uriIsJSONPointer = (ref: URI): boolean => {
42-
return ref.path() === '';
46+
export const uriIsJSONPointer = (ref: URI | ExtendedURI): boolean => {
47+
return (!('length' in ref) || ref.length > 0) && ref.path() === '';
4348
};

0 commit comments

Comments
 (0)