Skip to content

Commit 381acdd

Browse files
authored
feat(evaluate): add support for ApiDOM realm (#18)
Refs #13
1 parent e6af41e commit 381acdd

File tree

8 files changed

+678
-226
lines changed

8 files changed

+678
-226
lines changed

README.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,34 @@ const objectElement = new ObjectElement({
376376
a: ['b', 'c']
377377
});
378378

379-
evaluate(objectElement, '/a/1', { realm: new MinimEvaluationRealm() }); // => 'c'
379+
evaluate(objectElement, '/a/1', { realm: new MinimEvaluationRealm() }); // => StringElement('c')
380+
```
381+
382+
###### ApiDOM Evaluation Realm
383+
384+
The [ApiDOM](https://github.com/swagger-api/apidom) Evaluation Realm is an integration layer that enables
385+
evaluation of JSON Pointer expressions on ApiDOM structures. It provides compatibility with ApiDOM [core](https://github.com/swagger-api/apidom/tree/main/packages/apidom-core) and namespace packages (`@swagger-api/apidom-ns-*`),
386+
allowing to traverse and query ApiDOM element instances.
387+
388+
```js
389+
import { ObjectElement } from '@swagger-api/apidom-core';
390+
import { InfoElement } from '@swagger-api/apidom-ns-openapi-3-0'
391+
import { evaluate } from '@swaggerexpert/json-pointer';
392+
import ApiDOMEvaluationRealm from '@swaggerexpert/json-pointer/evaluate/realms/apidom';
393+
394+
const objectElement = new ObjectElement({
395+
a: ['b', 'c']
396+
});
397+
const infoElement = InfoElement.refract({
398+
contact: {
399+
name: 'SwaggerExpert',
400+
email: 'contact@swaggerexpert.com'
401+
}
402+
})
403+
404+
405+
evaluate(objectElement, '/a/1', { realm: new ApiDOMEvaluationRealm() }); // => StringElement('c')
406+
evaluate(infoElement, '/contact/name', { realm: new ApiDOMEvaluationRealm() }); // => StringElement('SwaggerExpert')
380407
```
381408

382409
###### Custom Evaluation Realms

package-lock.json

Lines changed: 169 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@
7777
"@babel/preset-env": "=7.26.9",
7878
"@commitlint/cli": "=19.8.0",
7979
"@commitlint/config-conventional": "=19.8.0",
80+
"@swagger-api/apidom-core": "^1.0.0-beta.30",
81+
"@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-beta.30",
8082
"apg-js": "^4.4.0",
8183
"babel-plugin-module-resolver": "^5.0.2",
8284
"chai": "=5.2.0",

src/evaluate/realms/apidom.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { isObjectElement, isArrayElement } from '@swagger-api/apidom-core';
2+
3+
import EvaluationRealm from '../EvaluationRealm.js';
4+
import JSONPointerKeyError from '../../errors/JSONPointerKeyError.js';
5+
6+
class ApiDOMEvaluationRealm extends EvaluationRealm {
7+
name = 'apidom';
8+
9+
isArray(node) {
10+
return isArrayElement(node);
11+
}
12+
13+
isObject(node) {
14+
return isObjectElement(node);
15+
}
16+
17+
sizeOf(node) {
18+
if (this.isArray(node) || this.isObject(node)) {
19+
return node.length;
20+
}
21+
return 0;
22+
}
23+
24+
has(node, referenceToken) {
25+
if (this.isArray(node)) {
26+
return Number(referenceToken) < this.sizeOf(node);
27+
}
28+
if (this.isObject(node)) {
29+
const keys = node.keys();
30+
const uniqueKeys = new Set(keys);
31+
32+
if (keys.length !== uniqueKeys.size) {
33+
throw new JSONPointerKeyError(`Object keys must be unique for '${referenceToken}'`, {
34+
currentValue: node,
35+
referenceToken,
36+
});
37+
}
38+
39+
return node.hasKey(referenceToken);
40+
}
41+
return false;
42+
}
43+
44+
evaluate(node, referenceToken) {
45+
if (this.isArray(node)) {
46+
return node.get(Number(referenceToken));
47+
}
48+
return node.get(referenceToken);
49+
}
50+
}
51+
52+
export default ApiDOMEvaluationRealm;

0 commit comments

Comments
 (0)