Skip to content

Commit

Permalink
fix: dereference is failing with url references (#69)
Browse files Browse the repository at this point in the history
* fix: errors on $ref resolving

* Fix JSON Pointer encoding

* Put some code back and fix an error on dereferencing

* Fix tests for Windows

* Point forked dependency to its own branch
  • Loading branch information
fmvilas authored Apr 20, 2020
1 parent 23d7439 commit a34028c
Show file tree
Hide file tree
Showing 16 changed files with 965 additions and 590 deletions.
4 changes: 2 additions & 2 deletions lib/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const path = require('path');
const Ajv = require('ajv');
const fetch = require('node-fetch');
const asyncapi = require('@asyncapi/specs');
const $RefParser = require('json-schema-ref-parser');
const $RefParser = require('@apidevtools/json-schema-ref-parser');
const mergePatch = require('tiny-merge-patch').apply;
const ParserError = require('./errors/parser-error');
const { toJS, findRefs, getLocationOf, improveAjvErrors } = require('./utils');
Expand Down Expand Up @@ -84,7 +84,7 @@ async function parse(asyncapiYAMLorJSON, options = {}) {
type: 'dereference-error',
title: err.message,
parsedJSON,
refs: findRefs(parsedJSON, err.path, options.path, initialFormat, asyncapiYAMLorJSON),
refs: findRefs(parsedJSON, err.originalPath || err.path, options.path, initialFormat, asyncapiYAMLorJSON),
});
}
} catch (e) {
Expand Down
35 changes: 28 additions & 7 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const path = require('path');
const YAML = require('js-yaml');
const { yamlAST, loc } = require('@fmvilas/pseudo-yaml-ast');
const jsonAST = require('json-to-ast');
Expand Down Expand Up @@ -105,13 +104,14 @@ utils.addExtensions = (obj) => {
return obj;
};

utils.findRefs = (json, absolutePath, relativeDir, initialFormat, asyncapiYAMLorJSON) => {
const relativePath = path.relative(relativeDir, absolutePath);
utils.findRefs = (json, absolutePath, relativePath, initialFormat, asyncapiYAMLorJSON) => {
let possibleRefUrls = [absolutePath];
if (absolutePath.startsWith(relativePath)) possibleRefUrls.push(absolutePath.substr(relativePath.length));
let refs = [];

traverse(json, (key, value, scope) => {
if (key === '$ref' && value === relativePath) {
refs.push({ location: [...scope, '$ref'] });
if (key === '$ref' && possibleRefUrls.includes(value)) {
refs.push({ location: [...scope.map(tilde), '$ref'] });
}
});

Expand Down Expand Up @@ -187,7 +187,7 @@ const findLocationOf = (keys, ast, initialFormat) => {

const findNode = (obj, location) => {
for (let key of location) {
obj = obj[key];
obj = obj[untilde(key)];
}
return obj;
};
Expand All @@ -196,7 +196,7 @@ const findNodeInAST = (ast, location) => {
let obj = ast;
for (let key of location) {
if (!Array.isArray(obj.children)) return;
const child = obj.children.find(c => c && c.type === 'Property' && c.key && c.key.value === key);
const child = obj.children.find(c => c && c.type === 'Property' && c.key && c.key.value === untilde(key));
if (!child) return;
obj = child.value;
}
Expand All @@ -211,3 +211,24 @@ const traverse = function (o, fn, scope = []) {
}
}
}

const tilde = (str) => {
return str.replace(/[~\/]{1}/g, (m) => {
switch (m) {
case '/': return '~1'
case '~': return '~0'
}
return m;
});
};

const untilde = (str) => {
if (!str.includes('~')) return str;
return str.replace(/~[01]/g, (m) => {
switch (m) {
case '~1': return '/'
case '~0': return '~'
}
return m;
});
};
Loading

0 comments on commit a34028c

Please sign in to comment.