diff --git a/lib/utils/index.js b/lib/utils/index.js index d624e66..09d9e62 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -3,6 +3,11 @@ * @description * Contains small utilities for djv project */ + +const REGEXP_URI = /:\/\//; +const REGEXP_URI_FRAGMENT = /#\/?/; +const REGEXP_URI_PATH = /(^[^:]+:\/\/.*\/).*/; + function cleanId(id) { return (id || '').replace(/#/g, ''); } @@ -20,12 +25,12 @@ function head(uri) { return uri; } - const parts = uri.split(/#\/?/); + const parts = uri.split(REGEXP_URI_FRAGMENT); return parts[0]; } function isFullUri(uri) { - return /:\/\//.test(uri); + return REGEXP_URI.test(uri); } /** @@ -39,7 +44,7 @@ function isFullUri(uri) { * @returns {string} path */ function path(uri) { - return uri.replace(/(^[^:]+:\/\/.*\/).*/, '$1'); + return uri.replace(REGEXP_URI_PATH, '$1'); } /** @@ -54,7 +59,7 @@ function fragment(uri) { return uri; } - const parts = uri.split(/#\/?/); + const parts = uri.split(REGEXP_URI_FRAGMENT); return parts[1]; } @@ -80,7 +85,7 @@ function makePath(parts) { return id; } - // if sharp delimiter found + // if fragment found if (id.indexOf('#') === 0) { // should replace uri's sharp with id const sharpUriIndex = uri.indexOf('#'); @@ -99,27 +104,24 @@ function hasProperty(object, property) { } function normalize(uri) { - return uri.replace(/~1/g, '/').replace(/~0/g, '~'); + return decodeURIComponent(uri.replace(/~1/g, '/').replace(/~0/g, '~')); } -function descent(reference, parentSchema) { - const name = fragment(reference); - const components = name && name.split('/'); - - let currentSchema = parentSchema; - // TODO change while to forEach - while (components && components.length > 0) { - const currentPath = decodeURIComponent(normalize(components[0])); - currentSchema = currentSchema[currentPath] || - (currentSchema.definitions && currentSchema.definitions[currentPath]); - - if (!currentSchema) { - throw new Error(`Schema ${name} not found`); - } - components.shift(); +function descent(uri, parentSchema) { + const uriFragment = fragment(uri); + if (!uriFragment) { + return parentSchema; } - return currentSchema; + const parts = uriFragment.split('/'); + return parts + .map(normalize) + .reduce((schema, part) => ( + schema[part] || ( + schema.definitions && + schema.definitions[part] + )) + , parentSchema); } module.exports = {