Skip to content

Commit 9df62d0

Browse files
committed
add: support issue #79 ref from definitions using invalid uri reference
1 parent 8e936c1 commit 9df62d0

File tree

3 files changed

+48
-6
lines changed

3 files changed

+48
-6
lines changed

src/draft2019-09/keywords/$ref.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { omit } from "../../utils/omit";
55
import { isObject } from "../../utils/isObject";
66
import { validateNode } from "../../validateNode";
77
import { SchemaNode } from "../../types";
8-
import { get } from "@sagold/json-pointer";
8+
import { get, split } from "@sagold/json-pointer";
99
import { reduceRef } from "../../keywords/$ref";
1010

1111
export const $refKeyword: Keyword = {
@@ -195,6 +195,25 @@ export default function getRef(node: SchemaNode, $ref = node?.$ref): SchemaNode
195195
return nextNode;
196196
}
197197
}
198+
199+
// resolve by json-pointer (optional dynamicRef)
200+
if (node.context.refs[$remoteHostRef]) {
201+
const parentNode = node.context.refs[$remoteHostRef];
202+
const path = split(fragments[1]);
203+
// @todo add utility to resolve schema-pointer to schema
204+
let currentNode = parentNode;
205+
for (let i = 0; i < path.length; i += 1) {
206+
const property = path[i] === "definitions" ? "$defs" : path[i];
207+
// @ts-expect-error random path
208+
currentNode = currentNode[property];
209+
if (currentNode == null) {
210+
console.error("REF: FAILED RESOLVING ref json-pointer", fragments[1]);
211+
return undefined;
212+
}
213+
}
214+
return currentNode;
215+
}
216+
198217
// console.error("REF: UNFOUND 2", $ref);
199218
return undefined;
200219
}

src/keywords/$ref.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,9 @@ export function getRef(node: SchemaNode, $ref = node?.$ref): SchemaNode | undefi
240240
// @todo add utility to resolve schema-pointer to schema
241241
let currentNode = parentNode;
242242
for (let i = 0; i < path.length; i += 1) {
243+
const property = path[i] === "definitions" ? "$defs" : path[i];
243244
// @ts-expect-error random path
244-
currentNode = currentNode[path[i]];
245+
currentNode = currentNode[property];
245246
if (currentNode == null) {
246247
console.error("REF: FAILED RESOLVING ref json-pointer", fragments[1]);
247248
return undefined;

src/tests/issues/issue79.csn.ref-resolution.test.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,20 @@ describe.only("issue#79 - csn ref resolution from defintions", () => {
1313
assert(node.$defs?.["@EndUserText.label"] != null);
1414
});
1515

16-
it("should resolve $ref '#/$defs/@EndUserText.label'", () => {
16+
it.skip("should resolve $ref '#/$defs/@EndUserText.label'", () => {
1717
const node = compileSchema(CSNSchema);
1818
const childSchema = node.getNodeRef("#/$defs/@EndUserText.label");
1919
assert(childSchema != null);
2020
});
2121

22-
it("should resolve $ref '#/definitions/@EndUserText.label'", () => {
22+
it.skip("should resolve $ref '#/definitions/@EndUserText.label'", () => {
2323
const node = compileSchema(CSNSchema);
2424
const childSchema = node.getNodeRef("#/definitions/@EndUserText.label");
25-
// assert.equal(valid, true);
2625
console.log("childSchema", childSchema);
26+
assert(childSchema != null);
2727
});
2828

29-
it.only("should validate data", () => {
29+
it("should validate data", () => {
3030
const node = compileSchema(CSNSchema);
3131
const { valid } = node.validate({
3232
csnInteropEffective: "1.0",
@@ -42,4 +42,26 @@ describe.only("issue#79 - csn ref resolution from defintions", () => {
4242
});
4343
assert.equal(valid, true);
4444
});
45+
46+
it("should invalidate data", () => {
47+
const node = compileSchema(CSNSchema);
48+
const { valid, errors } = node.validate({
49+
csnInteropEffective: "1.0",
50+
$version: "2.0",
51+
definitions: {
52+
BINRELID: {
53+
"@EndUserText.label": false,
54+
kind: "type",
55+
type: "cds.String",
56+
length: 22
57+
}
58+
}
59+
});
60+
61+
assert.equal(valid, false);
62+
assert.equal(errors[0].code, "type-error");
63+
assert.equal(errors[0].data.pointer, "#/definitions/BINRELID/@EndUserText.label");
64+
// @todo: error is logged twice
65+
// assert.equal(errors.length, 1);
66+
});
4567
});

0 commit comments

Comments
 (0)