use only one getreferences method
This commit is contained in:
Luis Tejeda
2022-05-05 12:30:31 -05:00
committed by Erik Mendoza
parent 5a0784165f
commit 1a208ab0ed
6 changed files with 168 additions and 193 deletions

View File

@@ -11,7 +11,7 @@ const slashes = /\//g,
* @param {string} filePathName the filePathName of the file
* @returns {string} - the encoded filepath
*/
function JsonPointerEncodeAndReplace(filePathName) {
function jsonPointerEncodeAndReplace(filePathName) {
return encodeURIComponent(filePathName.replace(tildes, '~0').replace(slashes, '~1'));
}
@@ -21,7 +21,7 @@ function JsonPointerEncodeAndReplace(filePathName) {
* @param {string} filePathName the filePathName of the file
* @returns {string} - the encoded filepath
*/
function JsonPointerDecodeAndReplace(filePathName) {
function jsonPointerDecodeAndReplace(filePathName) {
return decodeURIComponent(filePathName.replace(escapedSlash, '/').replace(escapedTilde, '~'));
}
@@ -37,14 +37,14 @@ function getKeyInComponents(componentName, filePathName, localPath) {
pointer,
localPathToCheck = localPath;
res.push(componentName);
res.push(JsonPointerDecodeAndReplace(filePathName));
res.push(jsonPointerDecodeAndReplace(filePathName));
if (localPath) {
if (localPath.startsWith('/')) {
localPathToCheck = localPath.substring(1);
}
pointer = localPathToCheck.split('/');
for (let i = 0; i < pointer.length; i++) {
pointer[i] = JsonPointerDecodeAndReplace(pointer[i]);
pointer[i] = jsonPointerDecodeAndReplace(pointer[i]);
}
res.push(...pointer);
}
@@ -99,10 +99,95 @@ function getJsonPointerRelationToRoot(encodeFunction, filePathName, refValue, co
return concatJsonPointer(encodeFunction, filePathName, componentName, localPath);
}
/**
* Checks if the input value is a valid url
* @param {string} stringToCheck - specified version of the process
* @returns {object} - Detect root files result object
*/
function stringIsAValidUrl(stringToCheck) {
try {
let url = new URL(stringToCheck);
if (url) {
return true;
}
return false;
}
catch (err) {
try {
let urlObj = url.parse(stringToCheck);
return urlObj.hostname !== null;
}
catch (parseErr) {
return false;
}
}
}
/**
* Determines if a value of a given key property of an object
* is an external reference with key $ref and value that does not start with #
* @param {object} obj - parent object of the $ref property
* @param {string} key - property key to check
* @returns {boolean} - true if the property key is $ref and the value does not start with #
* otherwise false
*/
function isExtRef(obj, key) {
return key === '$ref' &&
typeof obj[key] === 'string' &&
obj[key] !== undefined &&
!obj[key].startsWith(localPointer) &&
!stringIsAValidUrl(obj[key]);
}
/**
* Removes the local pointer inside a path
* aab.yaml#component returns aab.yaml
* @param {string} refValue - value of the $ref property
* @returns {string} - the calculated path only
*/
function removeLocalReferenceFromPath(refValue) {
if (refValue.$ref.includes(localPointer)) {
return refValue.$ref.split(localPointer)[0];
}
return refValue.$ref;
}
/**
* Determines if a value of a given key property of an object
* is a local reference with key $ref and value that starts with #
* @param {object} obj - parent object of the $ref property
* @param {string} key - property key to check
* @returns {boolean} - true if the property key is $ref and the value starts with #
* otherwise false
*/
function isLocalRef(obj, key) {
return key === '$ref' &&
typeof obj[key] === 'string' &&
obj[key] !== undefined &&
obj[key].startsWith(localPointer);
}
/**
* Extracts the entity's name from the json pointer
* @param {string} jsonPointer - pointer to get the name from
* @returns {boolean} - string: the name of the entity
*/
function getEntityName(jsonPointer) {
if (!jsonPointer) {
return '';
}
let segment = jsonPointer.substring(jsonPointer.lastIndexOf('/') + 1);
return segment;
}
module.exports = {
JsonPointerEncodeAndReplace,
JsonPointerDecodeAndReplace,
jsonPointerEncodeAndReplace,
jsonPointerDecodeAndReplace,
getJsonPointerRelationToRoot,
concatJsonPointer,
getKeyInComponents
getKeyInComponents,
isExtRef,
removeLocalReferenceFromPath,
isLocalRef,
getEntityName
};

View File

@@ -1,21 +1,7 @@
const traverseUtility = require('traverse'),
{ DFS } = require('./dfs'),
{ JsonPointerDecodeAndReplace } = require('./jsonPointer'),
deref = require('./deref.js'),
localPointer = '#';
/**
* Maps the output from get root files to detect root files
* @param {object} obj - output schema
* @param {string} key - specified version of the process
* @returns {object} - Detect root files result object
*/
function isLocalRef(obj, key) {
return key === '$ref' &&
typeof obj[key] === 'string' &&
obj[key] !== undefined &&
obj[key].startsWith(localPointer);
}
{ jsonPointerDecodeAndReplace, isLocalRef, getEntityName } = require('./jsonPointer'),
deref = require('./deref.js');
/**
* verifies if the path has been added to the result
@@ -27,42 +13,31 @@ function added(path, referencesInNode) {
return referencesInNode.find((reference) => { return reference.path === path; }) !== undefined;
}
function getLastSegmentURL(value) {
if (!value) {
return '';
}
let segment = value.substring(value.lastIndexOf('/') + 1);
return segment;
function pathSolver(property) {
return property.$ref;
}
/**
* Gets all the $refs from an object
* @param {object} currentNode - current node in process
* @param {object} refTypeResolver - function to resolve the ref according to type (local, external, web etc)
* @param {Function} refTypeResolver - function to resolve the ref according to type (local, external, web etc)
* @param {Function} pathSolver - function to resolve the Path
* @returns {object} - {path : $ref value}
*/
function getReferences (currentNode, refTypeResolver) {
function getReferences (currentNode, refTypeResolver, pathSolver) {
let referencesInNode = [];
// currentContent = currentNode.content,
// OASObject;
// if (currentNode.parsed) {
// OASObject = currentNode.parsed;
// }
// else {
// OASObject = parse.getOasObject(currentContent);
// }
traverseUtility(currentNode).forEach((property) => {
if (property) {
let hasReferenceTypeKey;
hasReferenceTypeKey = Object.keys(property)
.find(
(key) => {
return refTypeResolver(property, key);// change the function
return refTypeResolver(property, key);
}
);
if (hasReferenceTypeKey) {
if (!added(property.$ref, referencesInNode)) {
referencesInNode.push({ path: property.$ref });// change the local remover
referencesInNode.push({ path: pathSolver(property) });
}
}
}
@@ -80,7 +55,7 @@ function findNodeFromPath(referencePath, spec) {
let found,
splitRef = referencePath.split('/');
splitRef = splitRef.slice(1).map((elem) => {
return JsonPointerDecodeAndReplace(elem);
return jsonPointerDecodeAndReplace(elem);
});
found = deref._getEscaped(spec, splitRef);// really?
return found;
@@ -93,7 +68,7 @@ function findNodeFromPath(referencePath, spec) {
* @returns {object} - Detect root files result object
*/
function getAdjacentAndMissing(currentNode, spec) {
let currentNodeReferences = getReferences(currentNode, isLocalRef),
let currentNodeReferences = getReferences(currentNode, isLocalRef, pathSolver),
graphAdj = [],
missingNodes = [];
@@ -101,7 +76,7 @@ function getAdjacentAndMissing(currentNode, spec) {
let referencePath = reference.path,
adjacentNode = findNodeFromPath(referencePath, spec);
if (adjacentNode) {
adjacentNode.$info = { $ref: referencePath, name: getLastSegmentURL(referencePath) };
adjacentNode.$info = { $ref: referencePath, name: getEntityName(referencePath) };
graphAdj.push(adjacentNode);
}
else {
@@ -131,5 +106,6 @@ module.exports = {
getReferences,
getAdjacentAndMissing,
isLocalRef,
findNodeFromPath
findNodeFromPath,
pathSolver
};

View File

@@ -1,107 +1,11 @@
const traverseUtility = require('traverse'),
parse = require('./parse.js'),
const parse = require('./parse.js'),
BROWSER = 'browser',
{ DFS } = require('./dfs'),
localPointer = '#';
{ getReferences } = require('./relatedEntities'),
{ isExtRef, removeLocalReferenceFromPath } = require('./jsonPointer');
let path = require('path'),
url = require('url'),
pathBrowserify = require('path-browserify');
/**
* Checks if the input value is a valid url
* @param {string} stringToCheck - specified version of the process
* @returns {object} - Detect root files result object
*/
function stringIsAValidUrl(stringToCheck) {
try {
let url = new URL(stringToCheck);
if (url) {
return true;
}
return false;
}
catch (err) {
try {
let urlObj = url.parse(stringToCheck);
return urlObj.hostname !== null;
}
catch (parseErr) {
return false;
}
}
}
/**
* Maps the output from get root files to detect root files
* @param {object} obj - output schema
* @param {string} key - specified version of the process
* @returns {object} - Detect root files result object
*/
function isExtRef(obj, key) {
return key === '$ref' &&
typeof obj[key] === 'string' &&
obj[key] !== undefined &&
!obj[key].startsWith(localPointer) &&
!stringIsAValidUrl(obj[key]);
}
/**
* Removes the local pointer inside a path
* aab.yaml#component returns aab.yaml
* @param {string} refValue - value of the $ref property
* @returns {string} - the calculated path only
*/
function removeLocalReferenceFromPath(refValue) {
if (refValue.includes(localPointer)) {
return refValue.split(localPointer)[0];
}
return refValue;
}
/**
* verifies if the path has been added to the result
* @param {string} path - path to find
* @param {Array} referencesInNode - Array with the already added paths
* @returns {boolean} - wheter a node with the same path has been added
*/
function added(path, referencesInNode) {
return referencesInNode.find((reference) => { return reference.path === path; }) !== undefined;
}
/**
* Gets all the $refs from an object
* @param {object} currentNode - current node in data array input
* @returns {object} - {path : $ref value}
*/
function getReferences (currentNode) {
let referencesInNode = [],
currentContent = currentNode.content,
OASObject;
if (currentNode.parsed) {
OASObject = currentNode.parsed;
}
else {
OASObject = parse.getOasObject(currentContent);
}
traverseUtility(OASObject).forEach((property) => {
if (property) {
let hasReferenceTypeKey;
hasReferenceTypeKey = Object.keys(property)
.find(
(key) => {
return isExtRef(property, key);
}
);
if (hasReferenceTypeKey) {
if (!added(property.$ref, referencesInNode)) {
referencesInNode.push({ path: removeLocalReferenceFromPath(property.$ref) });
}
}
}
});
return referencesInNode;
}
/**
* Locates a referenced node from the data input by path
* @param {string} path1 - path1 to compare
@@ -165,9 +69,18 @@ function findNodeFromPath(referencePath, allData) {
* @returns {object} - Detect root files result object
*/
function getAdjacentAndMissing (currentNode, allData, specRoot) {
let currentNodeReferences = getReferences(currentNode),
let currentNodeReferences,
currentContent = currentNode.content,
graphAdj = [],
missingNodes = [];
missingNodes = [],
OASObject;
if (currentNode.parsed) {
OASObject = currentNode.parsed;
}
else {
OASObject = parse.getOasObject(currentContent);
}
currentNodeReferences = getReferences(OASObject, isExtRef, removeLocalReferenceFromPath);
currentNodeReferences.forEach((reference) => {
let referencePath = reference.path,
@@ -216,5 +129,6 @@ module.exports = {
getReferences,
getAdjacentAndMissing,
calculatePath,
calculatePathMissing
calculatePathMissing,
removeLocalReferenceFromPath
};

View File

@@ -1,6 +1,6 @@
const expect = require('chai').expect,
{ JsonPointerEncodeAndReplace,
{ jsonPointerEncodeAndReplace,
getJsonPointerRelationToRoot,
concatJsonPointer,
getKeyInComponents } = require('./../../lib/jsonPointer');
@@ -37,41 +37,41 @@ describe('getKeyInComponents function', function () {
describe('getJsonPointerRelationToRoot function', function () {
it('should return "#/components/schemas/Pets.yaml" no local path and schema', function () {
let res = getJsonPointerRelationToRoot(JsonPointerEncodeAndReplace, 'Pets.yaml', 'Pets.yaml', 'schemas');
let res = getJsonPointerRelationToRoot(jsonPointerEncodeAndReplace, 'Pets.yaml', 'Pets.yaml', 'schemas');
expect(res).to.equal('#/components/schemas/Pets.yaml');
});
it('should return "#/components/schemas/hello.yaml/definitions/world" no local path and schema', function () {
let res = getJsonPointerRelationToRoot(JsonPointerEncodeAndReplace, 'hello.yaml', 'hello.yaml#/definitions/world',
let res = getJsonPointerRelationToRoot(jsonPointerEncodeAndReplace, 'hello.yaml', 'hello.yaml#/definitions/world',
'schemas');
expect(res).to.equal('#/components/schemas/hello.yaml/definitions/world');
});
it('should return "#/components/schemas/Error" no file path', function () {
let res = getJsonPointerRelationToRoot(JsonPointerEncodeAndReplace, '', '#/components/schemas/Error', 'schemas');
let res = getJsonPointerRelationToRoot(jsonPointerEncodeAndReplace, '', '#/components/schemas/Error', 'schemas');
expect(res).to.equal('#/components/schemas/Error');
});
});
describe('concatJsonPointer function ', function () {
it('should return "#/components/schemas/Pets.yaml" no local path and schema', function () {
let res = concatJsonPointer(JsonPointerEncodeAndReplace, 'Pets.yaml', 'schemas');
let res = concatJsonPointer(jsonPointerEncodeAndReplace, 'Pets.yaml', 'schemas');
expect(res).to.equal('#/components/schemas/Pets.yaml');
});
it('should return "#/components/schemas/other~1Pets.yaml" no local path and schema folder in filename', function () {
let res = concatJsonPointer(JsonPointerEncodeAndReplace, 'other/Pets.yaml', 'schemas');
let res = concatJsonPointer(jsonPointerEncodeAndReplace, 'other/Pets.yaml', 'schemas');
expect(res).to.equal('#/components/schemas/other~1Pets.yaml');
});
it('should return "#/components/schemas/some~1Pet" no local path and schema folder in filename', function () {
let res = concatJsonPointer(JsonPointerEncodeAndReplace, 'some/Pet.yaml', 'schemas');
let res = concatJsonPointer(jsonPointerEncodeAndReplace, 'some/Pet.yaml', 'schemas');
expect(res).to.equal('#/components/schemas/some~1Pet.yaml');
});
it('should return "#/components/schemas/hello.yaml/definitions/world" no local path and schema', function () {
let res = concatJsonPointer(JsonPointerEncodeAndReplace, 'hello.yaml', 'schemas', '/definitions/world');
let res = concatJsonPointer(jsonPointerEncodeAndReplace, 'hello.yaml', 'schemas', '/definitions/world');
expect(res).to.equal('#/components/schemas/hello.yaml/definitions/world');
});
it('should return "#/components/schemas/~1Pets.yaml" no local path and schema', function () {
let res = concatJsonPointer(JsonPointerEncodeAndReplace, '/Pets.yaml', 'schemas');
let res = concatJsonPointer(jsonPointerEncodeAndReplace, '/Pets.yaml', 'schemas');
expect(res).to.equal('#/components/schemas/~1Pets.yaml');
});

View File

@@ -2,8 +2,17 @@ const { getReferences,
isLocalRef,
getAdjacentAndMissing,
findNodeFromPath,
getRelatedEntities } = require('./../../lib/relatedEntity'),
getRelatedEntities,
pathSolver } = require('./../../lib/relatedEntities'),
{ isExtRef,
removeLocalReferenceFromPath } = require('./../../lib/jsonPointer'),
path = require('path'),
expect = require('chai').expect,
PET_STORE_SEPARATED = '../data/petstore separate yaml/spec',
newPet = path.join(__dirname, PET_STORE_SEPARATED + '/NewPet.yaml'),
fs = require('fs'),
parse = require('./../../lib/parse.js'),
swaggerRoot = path.join(__dirname, PET_STORE_SEPARATED + '/swagger.yaml'),
mockedInputPetstore = {
'components': {
'schemas': {
@@ -59,7 +68,7 @@ describe('getReferences function', function () {
$ref: '#/components/schemas/Pet'
}
},
result = getReferences(inputNode, isLocalRef);
result = getReferences(inputNode, isLocalRef, pathSolver);
expect(result.length).to.equal(1);
expect(result[0].path).to.equal('#/components/schemas/Pet');
@@ -73,7 +82,7 @@ describe('getReferences function', function () {
newPet: { $ref: '#/components/schemas/Pet' }
}
},
result = getReferences(inputNode, isLocalRef);
result = getReferences(inputNode, isLocalRef, pathSolver);
expect(result.length).to.equal(1);
expect(result[0].path).to.equal('#/components/schemas/Pet');
});
@@ -86,9 +95,32 @@ describe('getReferences function', function () {
newPet: { $ref: 'Pet.yaml' }
}
},
result = getReferences(inputNode, isLocalRef);
result = getReferences(inputNode, isLocalRef, pathSolver);
expect(result.length).to.equal(0);
});
it('should return 1 reference from input', function () {
const parsedContentFile = parse.getOasObject(fs.readFileSync(newPet, 'utf8')),
result = getReferences(parsedContentFile, isExtRef, removeLocalReferenceFromPath);
expect(result.length).to.equal(1);
expect(result[0].path).to.equal('Pet.yaml');
});
it('should return unique references from input', function () {
const parsedContentFile = parse.getOasObject(fs.readFileSync(swaggerRoot, 'utf8')),
result = getReferences(parsedContentFile, isExtRef, removeLocalReferenceFromPath);
expect(result.length).to.equal(5);
expect(result[0].path).to.equal('parameters.yaml');
expect(result[1].path).to.equal('parameters.yaml');
expect(result[2].path).to.equal('Pet.yaml');
expect(result[3].path).to.equal('../common/Error.yaml');
expect(result[4].path).to.equal('NewPet.yaml');
});
});
describe('findNodeFromPath method', function () {

View File

@@ -1,4 +1,4 @@
const { getRelatedFiles, getReferences, getAdjacentAndMissing,
const { getRelatedFiles, getAdjacentAndMissing,
calculatePath, calculatePathMissing } = require('./../../lib/relatedFiles'),
expect = require('chai').expect,
fs = require('fs'),
@@ -54,38 +54,6 @@ describe('getAdjacentAndMissing function', function () {
});
});
describe('getReferences function', function () {
it('should return 1 reference from input', function () {
const contentFile = fs.readFileSync(newPet, 'utf8'),
inputNode = {
fileName: '/NewPet.yaml',
content: contentFile
},
result = getReferences(inputNode);
expect(result.length).to.equal(1);
expect(result[0].path).to.equal('Pet.yaml');
});
it('should return unique references from input', function () {
const contentFile = fs.readFileSync(swaggerRoot, 'utf8'),
inputNode = {
path: '/swagger.yaml',
content: contentFile
},
result = getReferences(inputNode);
expect(result.length).to.equal(5);
expect(result[0].path).to.equal('parameters.yaml');
expect(result[1].path).to.equal('parameters.yaml');
expect(result[2].path).to.equal('Pet.yaml');
expect(result[3].path).to.equal('../common/Error.yaml');
expect(result[4].path).to.equal('NewPet.yaml');
});
});
describe('getRelatedFiles function ', function () {
it('should return related in a folder structure with local pointers in $ref', function () {