Skip to content

Commit 3dc5c3a

Browse files
committed
feat: add support for errors and missing literals
Refs #35
1 parent fbe723a commit 3dc5c3a

File tree

7 files changed

+77
-21
lines changed

7 files changed

+77
-21
lines changed

apidom/packages/apidom-ast/src/ParseResult.ts

-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import Node from './Node';
55

66
interface ParseResult extends Node {
77
type: 'parseResult';
8-
errors: unknown[];
9-
annotations: unknown[];
108
rootNode: unknown;
119
}
1210

apidom/packages/apidom-parser-adapter-openapi3-1/src/parser/index.ts

+15-15
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,17 @@
11
import Parser from 'tree-sitter';
22
// @ts-ignore
33
import JSONLanguage from 'tree-sitter-json';
4-
import { JsonDocument, JsonObject, JsonProperty, JsonArray } from 'apidom-ast';
54
import $RefParser from '@apidevtools/json-schema-ref-parser';
65
import * as apiDOM from 'apidom';
6+
import { Error, JsonArray, JsonDocument, JsonObject, JsonProperty } from 'apidom-ast';
77
import openapi3_1 from 'apidom-ns-openapi3-1';
88
import { transform } from './cst';
99
import specification from './specification';
1010
import { visit } from './visitors';
1111

1212
const parse = async (
1313
source: string,
14-
{
15-
sourceMap = false,
16-
specObj = specification,
17-
keyMap = {
18-
// @ts-ignore
19-
[JsonDocument.type]: ['child'],
20-
// @ts-ignore
21-
[JsonObject.type]: ['properties'],
22-
// @ts-ignore
23-
[JsonProperty.type]: ['key', 'value'],
24-
// @ts-ignore
25-
[JsonArray.type]: ['items'],
26-
},
27-
} = {},
14+
{ sourceMap = false, specObj = specification } = {},
2815
): Promise<apiDOM.ParseResultElement> => {
2916
const resolvedSpecObj = await $RefParser.dereference(specObj);
3017
const namespace = apiDOM.createNamespace(openapi3_1);
@@ -39,6 +26,19 @@ const parse = async (
3926
const cst = parser.parse(source);
4027
const ast = transform(cst);
4128

29+
const keyMap = {
30+
// @ts-ignore
31+
[JsonDocument.type]: ['children'],
32+
// @ts-ignore
33+
[JsonObject.type]: ['children'],
34+
// @ts-ignore
35+
[JsonProperty.type]: ['children'],
36+
// @ts-ignore
37+
[JsonArray.type]: ['children'],
38+
// @ts-ignore
39+
[Error.type]: ['children'],
40+
};
41+
4242
visit(ast.rootNode, documentVisitor, {
4343
keyMap,
4444
// @ts-ignore

apidom/packages/apidom-parser-adapter-openapi3-1/src/parser/specification.ts

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import ServerVariableDescriptionVisitor from './visitors/open-api-3-1/server-var
2828
import ComponentsVisitor from './visitors/open-api-3-1/components';
2929
import SchemasVisitor from './visitors/open-api-3-1/components/SchemasVisitor';
3030
import SchemaVisitor from './visitors/open-api-3-1/SchemaVisitor';
31+
import ErrorVisitor from './visitors/ErrorVisitor';
3132
import { ValueVisitor, ObjectVisitor, ArrayVisitor } from './visitors/generics';
3233

3334
/**
@@ -43,6 +44,7 @@ const specification = {
4344
value: ValueVisitor,
4445
object: ObjectVisitor,
4546
array: ArrayVisitor,
47+
error: ErrorVisitor,
4648
document: {
4749
$visitor: DocumentVisitor,
4850
objects: {

apidom/packages/apidom-parser-adapter-openapi3-1/src/parser/visitors/DocumentVisitor.ts

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
11
import stampit from 'stampit';
2-
import { visit, BREAK } from '.';
2+
import { visit } from '.';
33
import SpecificationVisitor from './SpecificationVisitor';
44

55
const DocumentVisitor = stampit(SpecificationVisitor, {
66
methods: {
7+
literal(literalNode) {
8+
if (literalNode.isMissing) {
9+
const errorVisitor = this.retrieveVisitorInstance(['error']);
10+
visit(literalNode, errorVisitor);
11+
this.element.content.push(errorVisitor.element);
12+
}
13+
},
14+
715
document(documentNode) {
816
const openApiVisitor = this.retrieveVisitorInstance(['document', 'objects', 'OpenApi']);
917
visit(documentNode.child, openApiVisitor);
1018
this.element.content.push(openApiVisitor.element);
19+
},
1120

12-
return BREAK;
21+
error(errorNode) {
22+
const errorVisitor = this.retrieveVisitorInstance(['error']);
23+
visit(errorNode, errorVisitor);
24+
this.element.content.push(errorVisitor.element);
1325
},
1426
},
1527
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import stampit from 'stampit';
2+
import { BREAK } from '.';
3+
import SpecificationVisitor from './SpecificationVisitor';
4+
5+
const ErrorVisitor = stampit(SpecificationVisitor, {
6+
methods: {
7+
literal(literalNode) {
8+
if (literalNode.isMissing) {
9+
const message = `(Missing ${literalNode.value})`;
10+
this.element = new this.namespace.elements.Annotation(message);
11+
12+
this.maybeAddSourceMap(literalNode, this.element);
13+
14+
return BREAK;
15+
}
16+
17+
return undefined;
18+
},
19+
20+
error(errorNode) {
21+
const message = errorNode.isUnexpected
22+
? `(Unexpected ${errorNode.value})`
23+
: `(Error ${errorNode.value})`;
24+
25+
this.element = new this.namespace.elements.Annotation(message);
26+
this.element.classes.push('error');
27+
28+
this.maybeAddSourceMap(errorNode, this.element);
29+
30+
return BREAK;
31+
},
32+
},
33+
});
34+
35+
export default ErrorVisitor;

apidom/packages/apidom-parser-adapter-openapi3-1/src/parser/visitors/index.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import { JsonArray, JsonDocument, JsonObject, JsonProperty, visit as astVisit } from 'apidom-ast';
1+
import {
2+
JsonArray,
3+
JsonDocument,
4+
JsonObject,
5+
JsonProperty,
6+
Error,
7+
visit as astVisit,
8+
} from 'apidom-ast';
29

310
export { BREAK } from 'apidom-ast';
411

@@ -13,6 +20,8 @@ const keyMapDefault = {
1320
[JsonProperty.type]: ['key', 'value'],
1421
// @ts-ignore
1522
[JsonArray.type]: ['items'],
23+
// @ts-ignore
24+
[Error.type]: ['children'],
1625
};
1726

1827
// @ts-ignore

apidom/packages/apidom-parser-adapter-openapi3-1/test/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import * as adapter from '../src/adapter';
77
const spec = fs.readFileSync(path.join(__dirname, 'fixtures', 'sample-api.json')).toString();
88
// const namespace = apiDOM.createNamespace(openapi3);
99

10-
describe('apidom-parser', function () {
10+
describe('apidom-parser-adapter-openapi3-1', function () {
1111
it('test', async function () {
1212
console.log(adapter.detect(spec));
1313
console.log(adapter.mediaTypes);

0 commit comments

Comments
 (0)