diff --git a/lib/pointer.ts b/lib/pointer.ts index be021ee5..8ff3dd02 100644 --- a/lib/pointer.ts +++ b/lib/pointer.ts @@ -103,6 +103,21 @@ class Pointer { const token = tokens[i]; if (this.value[token] === undefined || (this.value[token] === null && i === tokens.length - 1)) { + // one final case is if the entry itself includes slashes, and was parsed out as a token - we can join the remaining tokens and try again + let didFindSubstringSlashMatch = false; + for (let j = tokens.length - 1; j > i; j--) { + const joinedToken = tokens.slice(i, j + 1).join("/"); + if (this.value[joinedToken] !== undefined) { + this.value = this.value[joinedToken]; + i = j; + didFindSubstringSlashMatch = true; + break; + } + } + if (didFindSubstringSlashMatch) { + continue; + } + this.value = null; throw new MissingPointerError(token, decodeURI(this.originalPath)); } else { diff --git a/test/specs/substrings/definitions/slash-strings.yaml b/test/specs/substrings/definitions/slash-strings.yaml new file mode 100644 index 00000000..5a28959e --- /dev/null +++ b/test/specs/substrings/definitions/slash-strings.yaml @@ -0,0 +1,8 @@ +channels: + 'smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured': + description: The topic on which measured values may be produced and consumed. + parameters: + streetlightId: + description: The ID of the streetlight. + schema: + type: string diff --git a/test/specs/substrings/slash.spec.ts b/test/specs/substrings/slash.spec.ts new file mode 100644 index 00000000..bf6bb0a0 --- /dev/null +++ b/test/specs/substrings/slash.spec.ts @@ -0,0 +1,24 @@ +import { describe, it } from "vitest"; +import $RefParser from "../../../lib/index.js"; +import path from "../../utils/path.js"; + +import { expect } from "vitest"; + +describe("$refs that include slashes", () => { + it("should parse successfully", async () => { + const parser = new $RefParser(); + await parser.parse(path.rel("test/specs/substrings/definitions/slash-strings.yaml")); + const $refs = parser.$refs; + const ref = $refs.get( + "#/channels/smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured/parameters", + ); + expect(ref).to.deep.equal({ + streetlightId: { + description: "The ID of the streetlight.", + schema: { + type: "string", + }, + }, + }); + }); +});