diff --git a/src/core/components/model.jsx b/src/core/components/model.jsx index e72edbd6d1f..4b420f367e6 100644 --- a/src/core/components/model.jsx +++ b/src/core/components/model.jsx @@ -3,6 +3,16 @@ import ImmutablePureComponent from "react-immutable-pure-component" import ImPropTypes from "react-immutable-proptypes" import PropTypes from "prop-types" +const decodeRefName = uri => { + const unescaped = uri.replace(/~1/g, "/").replace(/~0/g, "~") + + try { + return decodeURIComponent(unescaped) + } catch { + return unescaped + } +} + export default class Model extends ImmutablePureComponent { static propTypes = { schema: ImPropTypes.map.isRequired, @@ -22,10 +32,10 @@ export default class Model extends ImmutablePureComponent { getModelName =( ref )=> { if ( ref.indexOf("#/definitions/") !== -1 ) { - return ref.replace(/^.*#\/definitions\//, "") + return decodeRefName(ref.replace(/^.*#\/definitions\//, "")) } if ( ref.indexOf("#/components/schemas/") !== -1 ) { - return ref.replace(/^.*#\/components\/schemas\//, "") + return decodeRefName(ref.replace(/^.*#\/components\/schemas\//, "")) } } diff --git a/test/unit/core/helpers/get-model-name.js b/test/unit/core/helpers/get-model-name.js new file mode 100644 index 00000000000..2dbdd99c735 --- /dev/null +++ b/test/unit/core/helpers/get-model-name.js @@ -0,0 +1,39 @@ +/** + * @prettier + */ + +import Model from "../../../../src/core/components/model" + +describe("getModelName", () => { + const model = new Model() + + it("should decode JSON Pointer and URI encoding for OpenAPI v3 refs", () => { + const actual = model.getModelName("#/components/schemas/a~1b%2Bc") + const expected = "a/b+c" + + expect(actual).toStrictEqual(expected) + }) + + it("should decode JSON Pointer and URI encoding for Swagger v2 refs", () => { + const actual = model.getModelName( + "#/definitions/custom%3A%3Anamespace%3A%3APerson" + ) + const expected = "custom::namespace::Person" + + expect(actual).toStrictEqual(expected) + }) + + it("should decode multiple json-pointer values", () => { + const actual = model.getModelName("#/components/schemas/~1~1~0~0") + const expected = "//~~" + + expect(actual).toStrictEqual(expected) + }) + + it("should support invalid URI encoding", () => { + const actual = model.getModelName("#/components/schemas/%25%d") + const expected = "%25%d" + + expect(actual).toStrictEqual(expected) + }) +})