Skip to content

Commit

Permalink
fix: correctly parse $id and $comment JSDoc tags (#1129)
Browse files Browse the repository at this point in the history
Co-authored-by: Marcus <marcus.mailer@twobulls.com>
  • Loading branch information
then3rdman and MarcusAngel committed Feb 16, 2022
1 parent edf9d3a commit ac172d8
Show file tree
Hide file tree
Showing 14 changed files with 154 additions and 28 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -3,6 +3,8 @@ coverage/
dist/
node_modules/
!auto.config.ts
/.idea/

# local config for auto
.env

12 changes: 9 additions & 3 deletions src/AnnotationsReader/BasicAnnotationsReader.ts
Expand Up @@ -5,15 +5,17 @@ import { Annotations } from "../Type/AnnotatedType";
import { symbolAtNode } from "../Utils/symbolAtNode";

export class BasicAnnotationsReader implements AnnotationsReader {
private static requiresDollar = new Set<string>(["id", "comment"]);
private static textTags = new Set<string>([
"title",
"description",
"id",

"format",
"pattern",

// New since draft-07:
"$comment",
"comment",
"contentMediaType",
"contentEncoding",
]);
Expand Down Expand Up @@ -70,11 +72,15 @@ export class BasicAnnotationsReader implements AnnotationsReader {
const annotations = jsDocTags.reduce((result: Annotations, jsDocTag) => {
const value = this.parseJsDocTag(jsDocTag);
if (value !== undefined) {
result[jsDocTag.name] = value;
if (BasicAnnotationsReader.requiresDollar.has(jsDocTag.name)) {
result["$" + jsDocTag.name] = value;
} else {
result[jsDocTag.name] = value;
}
}

return result;
}, {});

return Object.keys(annotations).length ? annotations : undefined;
}

Expand Down
6 changes: 6 additions & 0 deletions src/Interfaces/AnnotationsReader.ts
@@ -0,0 +1,6 @@
import ts from "typescript";
import { Annotations } from "../Type/AnnotatedType";

export interface AnnotationsReader {
getAnnotations(node: ts.Node): Annotations | undefined;
}
5 changes: 5 additions & 0 deletions src/Interfaces/MutableParser.ts
@@ -0,0 +1,5 @@
import { SubNodeParser } from "./SubNodeParser";

export interface MutableParser {
addNodeParser(parser: SubNodeParser): MutableParser;
}
5 changes: 5 additions & 0 deletions src/Interfaces/MutableTypeFormatter.ts
@@ -0,0 +1,5 @@
import { SubTypeFormatter } from "./SubTypeFormatter";

export interface MutableTypeFormatter {
addTypeFormatter(formatter: SubTypeFormatter): MutableTypeFormatter;
}
6 changes: 6 additions & 0 deletions src/Interfaces/SubNodeParser.ts
@@ -0,0 +1,6 @@
import ts from "typescript";
import { NodeParser } from "../NodeParser";

export interface SubNodeParser extends NodeParser {
supportsNode(node: ts.Node): boolean;
}
6 changes: 6 additions & 0 deletions src/Interfaces/SubTypeFormatter.ts
@@ -0,0 +1,6 @@
import { BaseType } from "../Type/BaseType";
import { TypeFormatter } from "./TypeFormatter";

export interface SubTypeFormatter extends TypeFormatter {
supportsType(type: BaseType): boolean;
}
7 changes: 7 additions & 0 deletions src/Interfaces/TypeFormatter.ts
@@ -0,0 +1,7 @@
import { Definition } from "../Schema/Definition";
import { BaseType } from "../Type/BaseType";

export interface TypeFormatter {
getDefinition(type: BaseType): Definition;
getChildren(type: BaseType): BaseType[];
}
32 changes: 32 additions & 0 deletions test/valid-data-annotations.test.ts
@@ -0,0 +1,32 @@
import { assertValidSchema } from "./utils";

describe("valid-data-annotations", () => {
it(
"annotation-custom",
assertValidSchema("annotation-custom", "MyObject", "basic", [
"customNumberProperty",
"customStringProperty",
"customComplexProperty",
"customMultilineProperty",
"customUnquotedProperty",
])
);

it("annotation-empty-basic", assertValidSchema("annotation-empty", "MyObject", "basic", ["customEmptyAnnotation"]));
it(
"annotation-empty-extended",
assertValidSchema("annotation-empty", "MyObject", "extended", ["customEmptyAnnotation"])
);
it(
"annotation-deprecated-empty-basic",
assertValidSchema("annotation-deprecated-empty", "MyObject", "basic", ["customEmptyAnnotation"])
);
it(
"annotation-deprecated-empty-extended",
assertValidSchema("annotation-deprecated-empty", "MyObject", "extended", ["customEmptyAnnotation"])
);

it("annotation-comment", assertValidSchema("annotation-comment", "MyObject", "extended"));

it("annotation-id", assertValidSchema("annotation-id", "MyObject", "extended", [], "Test"));
});
25 changes: 0 additions & 25 deletions test/valid-data-other.test.ts
Expand Up @@ -59,31 +59,6 @@ describe("valid-data-other", () => {
it("generic-prefixed-number", assertValidSchema("generic-prefixed-number", "MyObject"));
it("generic-void", assertValidSchema("generic-void", "MyObject"));

it(
"annotation-custom",
assertValidSchema("annotation-custom", "MyObject", "basic", [
"customNumberProperty",
"customStringProperty",
"customComplexProperty",
"customMultilineProperty",
"customUnquotedProperty",
])
);

it("annotation-empty-basic", assertValidSchema("annotation-empty", "MyObject", "basic", ["customEmptyAnnotation"]));
it(
"annotation-empty-extended",
assertValidSchema("annotation-empty", "MyObject", "extended", ["customEmptyAnnotation"])
);
it(
"annotation-deprecated-empty-basic",
assertValidSchema("annotation-deprecated-empty", "MyObject", "basic", ["customEmptyAnnotation"])
);
it(
"annotation-deprecated-empty-extended",
assertValidSchema("annotation-deprecated-empty", "MyObject", "extended", ["customEmptyAnnotation"])
);

it("nullable-null", assertValidSchema("nullable-null", "MyObject"));

it("undefined-alias", assertValidSchema("undefined-alias", "MyType"));
Expand Down
15 changes: 15 additions & 0 deletions test/valid-data/annotation-comment/main.ts
@@ -0,0 +1,15 @@
/**
* @comment Top level comment
*/
export interface MyObject {
/**
* @comment Property comment
*/
nested: MyNestedObject
}

/**
* @comment Nested object comment
*/
export interface MyNestedObject {}

25 changes: 25 additions & 0 deletions test/valid-data/annotation-comment/schema.json
@@ -0,0 +1,25 @@
{
"$ref": "#/definitions/MyObject",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"MyNestedObject": {
"$comment": "Nested object comment",
"additionalProperties": false,
"type": "object"
},
"MyObject": {
"$comment": "Top level comment",
"additionalProperties": false,
"properties": {
"nested": {
"$comment": "Property comment",
"$ref": "#/definitions/MyNestedObject"
}
},
"required": [
"nested"
],
"type": "object"
}
}
}
11 changes: 11 additions & 0 deletions test/valid-data/annotation-id/main.ts
@@ -0,0 +1,11 @@
/**
* @id #MyObject
*/
export interface MyObject {
nested: MyNestedObject
}

/**
* @id #MyNestedObject
*/
export interface MyNestedObject {}
25 changes: 25 additions & 0 deletions test/valid-data/annotation-id/schema.json
@@ -0,0 +1,25 @@
{
"$id": "Test",
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/MyObject",
"definitions": {
"MyNestedObject": {
"$id": "#MyNestedObject",
"additionalProperties": false,
"type": "object"
},
"MyObject": {
"$id": "#MyObject",
"additionalProperties": false,
"properties": {
"nested": {
"$ref": "#/definitions/MyNestedObject"
}
},
"required": [
"nested"
],
"type": "object"
}
}
}

0 comments on commit ac172d8

Please sign in to comment.