Skip to content

Commit

Permalink
fix: support indexed circular access (#1593)
Browse files Browse the repository at this point in the history
fixes #1276
  • Loading branch information
domoritz committed Mar 3, 2023
1 parent 9b2b4bd commit fc08d89
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 15 deletions.
4 changes: 4 additions & 0 deletions src/NodeParser/IndexedAccessTypeNodeParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { BaseType } from "../Type/BaseType";
import { LiteralType } from "../Type/LiteralType";
import { NeverType } from "../Type/NeverType";
import { NumberType } from "../Type/NumberType";
import { ReferenceType } from "../Type/ReferenceType";
import { StringType } from "../Type/StringType";
import { TupleType } from "../Type/TupleType";
import { UnionType } from "../Type/UnionType";
Expand Down Expand Up @@ -67,6 +68,9 @@ export class IndexedAccessTypeNodeParser implements SubNodeParser {
if (type instanceof NumberType && objectType instanceof TupleType) {
return new UnionType(objectType.getTypes());
} else if (type instanceof LiteralType) {
if (objectType instanceof ReferenceType) {
return objectType;
}
throw new LogicError(`Invalid index "${type.getValue()}" in type "${objectType.getId()}"`);
} else {
throw new LogicError(`No additional properties in type "${objectType.getId()}"`);
Expand Down
4 changes: 4 additions & 0 deletions src/Type/ReferenceType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ export class ReferenceType extends BaseType {
return this.type;
}

public hasType(): boolean {
return this.type != null;
}

public setType(type: BaseType): void {
this.type = type;
this.setId(type.getId());
Expand Down
13 changes: 7 additions & 6 deletions src/Utils/derefType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import { BaseType } from "../Type/BaseType";
import { DefinitionType } from "../Type/DefinitionType";
import { ReferenceType } from "../Type/ReferenceType";

/**
* Dereference the type as far as possible.
*/
export function derefType(type: BaseType): BaseType {
if (
type instanceof ReferenceType ||
type instanceof DefinitionType ||
type instanceof AliasType ||
type instanceof AnnotatedType
) {
if (type instanceof DefinitionType || type instanceof AliasType || type instanceof AnnotatedType) {
return derefType(type.getType());
}
if (type instanceof ReferenceType && type.hasType()) {
return derefType(type.getType());
}

Expand Down
1 change: 1 addition & 0 deletions test/valid-data-type.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ describe("valid-data-type", () => {
assertMissingFormatterFor(new FunctionType(), "type-indexed-access-method-signature", "MyType")
);
it("type-indexed-circular-access", assertValidSchema("type-indexed-circular-access", "*"));
it("type-indexed-circular", assertValidSchema("type-indexed-circular", "MyType"));
it("type-keyof-tuple", assertValidSchema("type-keyof-tuple", "MyType"));
it("type-keyof-object", assertValidSchema("type-keyof-object", "MyType"));
it("type-keyof-object-function", assertValidSchema("type-keyof-object-function", "MyType"));
Expand Down
15 changes: 9 additions & 6 deletions test/valid-data/string-template-expression-literals/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
],
"type": "string"
},
"bool": {
"enum": [
"true!",
"false!"
],
"type": "string"
},
"foo": {
"enum": [
"ok",
Expand All @@ -21,15 +28,11 @@
],
"type": "string"
},
"ok": {
"const": "id_ok",
"type": "string"
},
"num": {
"type": "string"
},
"bool": {
"enum": ["true!", "false!"],
"ok": {
"const": "id_ok",
"type": "string"
}
},
Expand Down
9 changes: 9 additions & 0 deletions test/valid-data/type-indexed-circular/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface GeoJsonObject {
type: GeometryCollection["type"];
}

export interface GeometryCollection extends GeoJsonObject {
type: "GeometryCollection";
}

export type MyType = GeometryCollection;
22 changes: 22 additions & 0 deletions test/valid-data/type-indexed-circular/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"$ref": "#/definitions/MyType",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"GeometryCollection": {
"additionalProperties": false,
"properties": {
"type": {
"const": "GeometryCollection",
"type": "string"
}
},
"required": [
"type"
],
"type": "object"
},
"MyType": {
"$ref": "#/definitions/GeometryCollection"
}
}
}
5 changes: 2 additions & 3 deletions test/vega-lite.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@ import stringify from "safe-stable-stringify";

describe("vega-lite", () => {
it("schema", () => {
const type = "TopLevelSpec";
const config: Config = {
path: `node_modules/vega-lite/src/index.ts`,
type,
type: "TopLevelSpec",
encodeRefs: false,
skipTypeCheck: true,
};

const generator = createGenerator(config);
const schema = generator.createSchema(type);
const schema = generator.createSchema(config.type);
const schemaFile = resolve("test/vega-lite/schema.json");

if (process.env.UPDATE_SCHEMA) {
Expand Down

0 comments on commit fc08d89

Please sign in to comment.