@stoplight/json-schema-ref-parser
Advanced tools
Comparing version 9.1.0-beta.1 to 9.1.0-beta.2
@@ -5,3 +5,3 @@ "use strict"; | ||
function generateBase (defaultRoot) { | ||
function generateBase (defaultRoot, opts) { | ||
let suggestions = createSuggester(defaultRoot); | ||
@@ -13,14 +13,28 @@ | ||
generateKey (schema, file, hash) { | ||
if (!url.isFileSystemPath(file)) { | ||
if (!url.isFileSystemPath(file) && !url.isHttp(file)) { | ||
return null; | ||
} | ||
if (opts && typeof opts.preprocessFilepath === "function") { | ||
file = opts.preprocessFilepath(file); | ||
} | ||
if (hash !== "#" && hash !== null) { | ||
let existingSuggestion = suggestions.getExistingSuggestion(file); | ||
if (existingSuggestion === null) { | ||
return null; | ||
} | ||
if (!suggestions.isInRoot(hash)) { | ||
return suggestions.getExistingSuggestion(file) + hash.slice(1); | ||
return null; | ||
} | ||
return suggestions.suggestNameForPointer(schema, suggestions.getExistingSuggestion(file) + hash.slice(1)); | ||
return suggestions.suggestNameForPointer(schema, existingSuggestion + hash.slice(1)); | ||
} | ||
if (url.isHttp(file)) { | ||
return suggestions.suggestNameForUrl(schema, file); | ||
} | ||
return suggestions.suggestNameForFilePath(schema, file); | ||
@@ -34,21 +48,21 @@ }, | ||
module.exports.getDefaultsForOldJsonSchema = function () { | ||
return generateBase("#/definitions"); | ||
module.exports.getDefaultsForOldJsonSchema = function (opts) { | ||
return generateBase("#/definitions", opts); | ||
}; | ||
module.exports.getDefaultsForNewJsonSchema = function () { | ||
return generateBase("#/$defs"); | ||
module.exports.getDefaultsForNewJsonSchema = function (opts) { | ||
return generateBase("#/$defs", opts); | ||
}; | ||
module.exports.getDefaultsForOAS2 = function () { | ||
let opts = generateBase("#/definitions"); | ||
module.exports.getDefaultsForOAS2 = function (opts) { | ||
let base = generateBase("#/definitions", opts); | ||
return { | ||
...opts, | ||
...base, | ||
generateKey (schema, file, hash) { | ||
if (hash !== "#" && hash !== null) { | ||
return opts.generateKey(schema, file, hash.replace(/\/components\/schemas\//g, "/definitions/")); | ||
return base.generateKey(schema, file, hash.replace(/\/components\/schemas\//g, "/definitions/")); | ||
} | ||
return opts.generateKey(schema, file, hash); | ||
return base.generateKey(schema, file, hash); | ||
}, | ||
@@ -62,13 +76,13 @@ shouldInline (pathFromRoot) { | ||
module.exports.getDefaultsForOAS3 = function () { | ||
let opts = generateBase("#/components/schemas"); | ||
module.exports.getDefaultsForOAS3 = function (opts) { | ||
let base = generateBase("#/components/schemas", opts); | ||
return { | ||
...opts, | ||
...base, | ||
generateKey (schema, file, hash) { | ||
if (hash !== "#" && hash !== null) { | ||
return opts.generateKey(schema, file, hash.replace(/\/definitions\//g, "/components/schemas/")); | ||
return base.generateKey(schema, file, hash.replace(/\/definitions\//g, "/components/schemas/")); | ||
} | ||
return opts.generateKey(schema, file, hash); | ||
return base.generateKey(schema, file, hash); | ||
}, | ||
@@ -75,0 +89,0 @@ shouldInline (pathFromRoot) { |
@@ -6,3 +6,3 @@ "use strict"; | ||
const url = require("../util/url"); | ||
const { safePointerToPath } = require("../util/url"); | ||
const { safePathToPointer, safePointerToPath } = require("../util/url"); | ||
const { get, set } = require("./util/object"); | ||
@@ -94,10 +94,11 @@ | ||
let keys = Object.keys(roots); | ||
if (keys.length === 1) { | ||
return (roots["#"] === null ? pathFromRoot : roots["#"]) + hash.slice(1); | ||
if (keys.length === 0 || roots["#"] === null) { | ||
return pathFromRoot; | ||
} | ||
keys = keys.filter(key => roots[key] !== null); | ||
keys.sort((a, b) => b.length - a.length); | ||
let customRoot = keys.find(root => hash.startsWith(root)); | ||
return roots[customRoot] === null ? pathFromRoot : roots[customRoot] + hash.replace(customRoot, ""); | ||
return roots[customRoot] + hash.replace(customRoot, ""); | ||
} | ||
@@ -262,3 +263,3 @@ | ||
// if entry is not inlineable and has a custom root linked, we need to remap the properties of the object | ||
if (!entry.inlineable && customRoots[entry.file] && customRoots[entry.file][entry.hash]) { | ||
if (!entry.inlineable && customRoots[entry.file] && entry.hash in customRoots[entry.file] && customRoots[entry.file]["#"] !== null) { | ||
if (entry.hash === "#") { | ||
@@ -270,3 +271,4 @@ // the whole file is referenced for the first time | ||
} | ||
else { | ||
// entry is not supposed to be moved anywhere, it's not placed under root | ||
else if (customRoots[entry.file][entry.hash] !== null) { | ||
// a portion of previously referenced (and injected) file is referenced | ||
@@ -278,3 +280,3 @@ // we may need to hoist some of its properties, i.e. `external-file.json#/definitions/foo/definitions/bar` gets remapped to `#/definitions/foo_bar` | ||
// value = in fact we do `get(value, ['definitions', 'foo', 'definitions']);` // it's a bit noisy cause we want to handle a potential edge case here | ||
let value = get(subschema, `#/${parsedHash.length === 1 ? parsedHash[0] : parsedHash.slice(0, parsedHash.length - 1).join("/")}`); | ||
let value = get(subschema, safePathToPointer(parsedHash.length === 1 ? parsedHash : parsedHash.slice(0, parsedHash.length - 1))); | ||
// we set the value at relevant spot - this is the first step of the move operation | ||
@@ -281,0 +283,0 @@ // for our scenario, it'd look as follows `set(schema, ['definitions', 'foo_bar'], value['bar']);` |
"use strict"; | ||
const { safePointerToPath } = require("../../util/url"); | ||
const { safePointerToPath, parse } = require("../../util/url"); | ||
const { basename, extname } = require("@stoplight/path"); | ||
@@ -9,2 +9,22 @@ const { get } = require("./object"); | ||
function isVersionId (str, letter, i) { | ||
if (letter !== "v") { | ||
return false; | ||
} | ||
i += 2; | ||
for (; i < str.length; i++) { | ||
if (!Number.isNaN(Number(str[i]))) { | ||
continue; | ||
} | ||
if (str[i] === ".") { | ||
return true; | ||
} | ||
} | ||
return str.length === i; | ||
} | ||
function capitalize (name) { | ||
@@ -15,3 +35,11 @@ return name[0].toUpperCase() + name.slice(1); | ||
function prettify (name) { | ||
return capitalize(name.replace(/(?:\.|[\\/]+)([a-z])?/g, (_, letter, i) => { | ||
return capitalize(name.replace(/(?:\.|[\\/]+)(mid|[a-z])?/g, (_, letter, i) => { | ||
if (isVersionId(name, letter, i)) { | ||
return `.${letter}`; | ||
} | ||
if (letter === "mid") { | ||
return "_m"; | ||
} | ||
return letter === undefined ? i === 0 ? "" : "_" : `_${letter.toUpperCase()}`; | ||
@@ -59,2 +87,16 @@ })); | ||
suggestNameForUrl (schema, url) { | ||
if (!computed[url]) { | ||
try { | ||
const { href } = parse(url, true); | ||
computed[url] = this.suggestNameForFilePath(schema, href); | ||
} | ||
catch { | ||
computed[url] = null; | ||
} | ||
} | ||
return computed[url]; | ||
}, | ||
isInRoot (pointer) { | ||
@@ -61,0 +103,0 @@ let parsedPointer = safePointerToPath(pointer); |
@@ -7,2 +7,4 @@ "use strict"; | ||
url = module.exports, | ||
slash = /\//g, | ||
tilde = /~/g, | ||
jsonPointerSlash = /~1/g, | ||
@@ -259,1 +261,17 @@ jsonPointerTilde = /~0/g; | ||
}; | ||
/** | ||
* Converts a valid JSON Path to a pointer | ||
* | ||
* @param {Array<number | string>} path | ||
* @returns {string} | ||
*/ | ||
exports.safePathToPointer = function safePointerToPath (path) { | ||
if (path.length === 0) { | ||
return "#"; | ||
} | ||
return `#/${path.map(segment => { | ||
return typeof segment === "number" ? String(segment) : segment.replace(tilde, "~0").replace(slash, "~1"); | ||
}).join("/")}`; | ||
}; |
{ | ||
"name": "@stoplight/json-schema-ref-parser", | ||
"version": "9.1.0-beta.1", | ||
"version": "9.1.0-beta.2", | ||
"description": "Parse, Resolve, and Dereference JSON Schema $ref pointers", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
163584
28
3519