From 76dbdf83f13ecccf84c60f87143202d343545ce0 Mon Sep 17 00:00:00 2001 From: solvedDev Date: Sun, 12 Jun 2022 18:08:32 +0200 Subject: [PATCH 1/6] upd: initial scaffold --- src/components/JSONSchema/ToTypes/Array.ts | 11 +++++++++++ src/components/JSONSchema/ToTypes/Interface.ts | 18 ++++++++++++++++++ src/components/JSONSchema/ToTypes/Primitive.ts | 13 +++++++++++++ src/components/JSONSchema/ToTypes/Tuple.ts | 11 +++++++++++ src/components/JSONSchema/ToTypes/Type.ts | 3 +++ 5 files changed, 56 insertions(+) create mode 100644 src/components/JSONSchema/ToTypes/Array.ts create mode 100644 src/components/JSONSchema/ToTypes/Interface.ts create mode 100644 src/components/JSONSchema/ToTypes/Primitive.ts create mode 100644 src/components/JSONSchema/ToTypes/Tuple.ts create mode 100644 src/components/JSONSchema/ToTypes/Type.ts diff --git a/src/components/JSONSchema/ToTypes/Array.ts b/src/components/JSONSchema/ToTypes/Array.ts new file mode 100644 index 000000000..13563c4cf --- /dev/null +++ b/src/components/JSONSchema/ToTypes/Array.ts @@ -0,0 +1,11 @@ +import { Type } from './Type' + +export class Array extends Type { + constructor(public readonly type: Type) { + super() + } + + public toString() { + return `${this.type.toString()}[]` + } +} diff --git a/src/components/JSONSchema/ToTypes/Interface.ts b/src/components/JSONSchema/ToTypes/Interface.ts new file mode 100644 index 000000000..532e80738 --- /dev/null +++ b/src/components/JSONSchema/ToTypes/Interface.ts @@ -0,0 +1,18 @@ +import { Type } from './Type' + +export class Interface extends Type { + protected properties: Record = {} + + addProperty(name: string, type: Type) { + this.properties[name] = type + } + + toString() { + return `{ + ${Object.entries(this.properties) + .map(([key, type]) => `\t${key}: ${type.toString()}`) + .join('\n')} + [k: string]: any + }` + } +} diff --git a/src/components/JSONSchema/ToTypes/Primitive.ts b/src/components/JSONSchema/ToTypes/Primitive.ts new file mode 100644 index 000000000..f89f8846b --- /dev/null +++ b/src/components/JSONSchema/ToTypes/Primitive.ts @@ -0,0 +1,13 @@ +import { Type } from './Type' + +export class PrimitiveType extends Type { + constructor( + protected primitiveType: 'string' | 'number' | 'boolean' | 'null' + ) { + super() + } + + public toString() { + return this.primitiveType + } +} diff --git a/src/components/JSONSchema/ToTypes/Tuple.ts b/src/components/JSONSchema/ToTypes/Tuple.ts new file mode 100644 index 000000000..4be4f0334 --- /dev/null +++ b/src/components/JSONSchema/ToTypes/Tuple.ts @@ -0,0 +1,11 @@ +import { Type } from './Type' + +export class Tuple extends Type { + constructor(public readonly types: Type[]) { + super() + } + + public toString() { + return `[${this.types.map((type) => type.toString()).join(', ')}]` + } +} diff --git a/src/components/JSONSchema/ToTypes/Type.ts b/src/components/JSONSchema/ToTypes/Type.ts new file mode 100644 index 000000000..14a80c85b --- /dev/null +++ b/src/components/JSONSchema/ToTypes/Type.ts @@ -0,0 +1,3 @@ +export abstract class Type { + public abstract toString(): string +} From b83823e5b7aa6c41955549d8244ba55d8f30fa00 Mon Sep 17 00:00:00 2001 From: solvedDev <33347616+solvedDev@users.noreply.github.com> Date: Sun, 12 Jun 2022 18:50:05 +0200 Subject: [PATCH 2/6] upd: progress --- src/components/JSONSchema/Schema/AllOf.ts | 1 + src/components/JSONSchema/Schema/Items.ts | 17 +++++++++++++++++ src/components/JSONSchema/Schema/Parent.ts | 8 ++++++++ src/components/JSONSchema/Schema/Properties.ts | 14 ++++++++++++++ src/components/JSONSchema/Schema/Ref.ts | 4 ++++ src/components/JSONSchema/Schema/Schema.ts | 6 ++++++ src/components/JSONSchema/Schema/ThenSchema.ts | 4 ++++ src/components/JSONSchema/Schema/Type.ts | 14 ++++++++++++++ src/components/JSONSchema/ToTypes/Array.ts | 2 +- src/components/JSONSchema/ToTypes/Primitive.ts | 15 ++++++++++++--- src/components/JSONSchema/ToTypes/Union.ts | 9 +++++++++ 11 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 src/components/JSONSchema/ToTypes/Union.ts diff --git a/src/components/JSONSchema/Schema/AllOf.ts b/src/components/JSONSchema/Schema/AllOf.ts index 644cb40ac..09dcfc06c 100644 --- a/src/components/JSONSchema/Schema/AllOf.ts +++ b/src/components/JSONSchema/Schema/AllOf.ts @@ -1,6 +1,7 @@ import { ParentSchema } from './Parent' import { RootSchema } from './Root' import { Schema } from './Schema' +import { UnionType } from '../ToTypes/Union' export class AllOfSchema extends ParentSchema { protected children: Schema[] diff --git a/src/components/JSONSchema/Schema/Items.ts b/src/components/JSONSchema/Schema/Items.ts index 6cee3b6a7..8f751ca8b 100644 --- a/src/components/JSONSchema/Schema/Items.ts +++ b/src/components/JSONSchema/Schema/Items.ts @@ -1,5 +1,7 @@ import { RootSchema } from './Root' import { IDiagnostic, Schema } from './Schema' +import { Tuple } from '../ToTypes/Tuple' +import { ArrayType } from '../ToTypes/Array' export class ItemsSchema extends Schema { protected children: Schema | Schema[] @@ -67,4 +69,19 @@ export class ItemsSchema extends Schema { validate(obj: unknown) { return [] } + + override toTypeDefinitions() { + if (Array.isArray(this.children)) { + return new Tuple( + this.children + .map((child) => child.toTypeDefinitions()) + .filter((type) => type !== null) + ) + } else { + const type = this.children.toTypeDefinitions() + if (type === null) return null + + return new ArrayType(type) + } + } } diff --git a/src/components/JSONSchema/Schema/Parent.ts b/src/components/JSONSchema/Schema/Parent.ts index e2dc11db1..174b1f121 100644 --- a/src/components/JSONSchema/Schema/Parent.ts +++ b/src/components/JSONSchema/Schema/Parent.ts @@ -30,4 +30,12 @@ export abstract class ParentSchema extends Schema { return children } + + override toTypeDefinitions() { + return new UnionType( + this.children + .map((child) => child.toTypeDefinitions()) + .filter((child) => child !== null) + ) + } } diff --git a/src/components/JSONSchema/Schema/Properties.ts b/src/components/JSONSchema/Schema/Properties.ts index 6b9534b1a..732ad7775 100644 --- a/src/components/JSONSchema/Schema/Properties.ts +++ b/src/components/JSONSchema/Schema/Properties.ts @@ -1,5 +1,6 @@ import { RootSchema } from './Root' import { IDiagnostic, Schema } from './Schema' +import { Interface } from '../ToTypes/Interface' export class PropertiesSchema extends Schema { protected children: Record = {} @@ -74,4 +75,17 @@ export class PropertiesSchema extends Schema { return diagnostics } + + override toTypeDefinitions() { + const interface = new Interface() + + for (const [propertyName, child] of Object.entries(this.children)) { + const type = child.toTypeDefinitions() + if (type === null) continue + + interface.addProperty(propertyName, type) + } + + return interface + } } diff --git a/src/components/JSONSchema/Schema/Ref.ts b/src/components/JSONSchema/Schema/Ref.ts index aae8f1894..53a48adb9 100644 --- a/src/components/JSONSchema/Schema/Ref.ts +++ b/src/components/JSONSchema/Schema/Ref.ts @@ -74,4 +74,8 @@ export class RefSchema extends Schema { getFreeIfSchema() { return this.rootSchema.getFreeIfSchema() } + + override toTypeDefinitions() { + return this.rootSchema.toTypeDefinitions() + } } diff --git a/src/components/JSONSchema/Schema/Schema.ts b/src/components/JSONSchema/Schema/Schema.ts index 274d772ec..3e3481e5e 100644 --- a/src/components/JSONSchema/Schema/Schema.ts +++ b/src/components/JSONSchema/Schema/Schema.ts @@ -1,3 +1,5 @@ +import { Type } from '../ToTypes/Type' + export interface ISchemaResult { diagnostics: IDiagnostic[] } @@ -42,4 +44,8 @@ export abstract class Schema { obj: unknown, location: (string | number)[] ): Schema[] + + toTypeDefinitions(): Type | null { + return null + } } diff --git a/src/components/JSONSchema/Schema/ThenSchema.ts b/src/components/JSONSchema/Schema/ThenSchema.ts index e5352cd59..90d9deb0e 100644 --- a/src/components/JSONSchema/Schema/ThenSchema.ts +++ b/src/components/JSONSchema/Schema/ThenSchema.ts @@ -38,4 +38,8 @@ export class ThenSchema extends Schema { if (this.ifSchema.isTrue(obj)) return this.rootSchema.validate(obj) return [] } + + override toTypeDefinitions() { + return this.rootSchema.toTypeDefinitions() + } } diff --git a/src/components/JSONSchema/Schema/Type.ts b/src/components/JSONSchema/Schema/Type.ts index 9779ff8b8..75716b5a1 100644 --- a/src/components/JSONSchema/Schema/Type.ts +++ b/src/components/JSONSchema/Schema/Type.ts @@ -1,5 +1,7 @@ import { ICompletionItem, Schema } from './Schema' import { getTypeOf } from '/@/utils/typeof' +import { PrimitiveType, TSupportedPrimitiveTypes } from '../ToTypes/Primitive' +import { UnionType } from '../ToTypes/Union' export class TypeSchema extends Schema { get values() { @@ -60,4 +62,16 @@ export class TypeSchema extends Schema { return [] } + + override toTypeDefinitions() { + const values = ( + Array.isArray(this.value) ? this.value : [this.value] + ).filter((type) => !['object', 'array'].includes(type)) + + return new UnionType( + values.map( + (val) => new PrimitiveType(PrimitiveType.toTypeScriptType(val)) + ) + ) + } } diff --git a/src/components/JSONSchema/ToTypes/Array.ts b/src/components/JSONSchema/ToTypes/Array.ts index 13563c4cf..91a49599f 100644 --- a/src/components/JSONSchema/ToTypes/Array.ts +++ b/src/components/JSONSchema/ToTypes/Array.ts @@ -1,6 +1,6 @@ import { Type } from './Type' -export class Array extends Type { +export class ArrayType extends Type { constructor(public readonly type: Type) { super() } diff --git a/src/components/JSONSchema/ToTypes/Primitive.ts b/src/components/JSONSchema/ToTypes/Primitive.ts index f89f8846b..fb4866080 100644 --- a/src/components/JSONSchema/ToTypes/Primitive.ts +++ b/src/components/JSONSchema/ToTypes/Primitive.ts @@ -1,12 +1,21 @@ import { Type } from './Type' +export type TSupportedPrimitiveTypes = 'string' | 'number' | 'boolean' | 'null' + export class PrimitiveType extends Type { - constructor( - protected primitiveType: 'string' | 'number' | 'boolean' | 'null' - ) { + constructor(protected primitiveType: TSupportedPrimitiveTypes) { super() } + static toTypeScriptType( + jsonSchemaType: 'boolean' | 'string' | 'decimal' | 'integer' | 'null' + ) { + if ((jsonSchemaType === 'decimal') | (type === 'integer')) + return 'number' + + return jsonSchemaType + } + public toString() { return this.primitiveType } diff --git a/src/components/JSONSchema/ToTypes/Union.ts b/src/components/JSONSchema/ToTypes/Union.ts new file mode 100644 index 000000000..f41a224ba --- /dev/null +++ b/src/components/JSONSchema/ToTypes/Union.ts @@ -0,0 +1,9 @@ +import { Type } from '../ToTypes/Type' + +export class UnionType extends Type { + constructor(protected types: Type[]) {} + + toString() { + return this.types.map((type) => type.toString()).join(' | ') + } +} From 36eb2ed8637c427c1c47673f0e43daaef9e49f51 Mon Sep 17 00:00:00 2001 From: solvedDev <33347616+solvedDev@users.noreply.github.com> Date: Sun, 12 Jun 2022 19:22:52 +0200 Subject: [PATCH 3/6] upd: progress --- src/components/JSONSchema/Schema/Const.ts | 6 +++++- .../JSONSchema/Schema/ElseSchema.ts | 4 ++++ src/components/JSONSchema/Schema/Enum.ts | 5 +++++ .../JSONSchema/ToTypes/Interface.ts | 4 ++-- src/components/JSONSchema/ToTypes/Literal.ts | 21 +++++++++++++++++++ 5 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 src/components/JSONSchema/ToTypes/Literal.ts diff --git a/src/components/JSONSchema/Schema/Const.ts b/src/components/JSONSchema/Schema/Const.ts index d5652284f..68ea1ac17 100644 --- a/src/components/JSONSchema/Schema/Const.ts +++ b/src/components/JSONSchema/Schema/Const.ts @@ -1,7 +1,7 @@ +import { LiteralType } from '../ToTypes/Literal' import { Schema } from './Schema' export class ConstSchema extends Schema { - public readonly types = [] getSchemasFor() { return [] } @@ -21,4 +21,8 @@ export class ConstSchema extends Schema { ] return [] } + + override toTypeDefinitions() { + return new LiteralType(this.value) + } } diff --git a/src/components/JSONSchema/Schema/ElseSchema.ts b/src/components/JSONSchema/Schema/ElseSchema.ts index db2458a04..082ecf10d 100644 --- a/src/components/JSONSchema/Schema/ElseSchema.ts +++ b/src/components/JSONSchema/Schema/ElseSchema.ts @@ -38,4 +38,8 @@ export class ElseSchema extends Schema { if (!this.ifSchema.isTrue(obj)) return this.rootSchema.validate(obj) return [] } + + override toTypeDefinitions() { + return this.rootSchema.toTypeDefinitions() + } } diff --git a/src/components/JSONSchema/Schema/Enum.ts b/src/components/JSONSchema/Schema/Enum.ts index e0c167729..6ab9c2ffd 100644 --- a/src/components/JSONSchema/Schema/Enum.ts +++ b/src/components/JSONSchema/Schema/Enum.ts @@ -1,3 +1,4 @@ +import { LiteralType } from '../ToTypes/Literal' import { Schema } from './Schema' export class EnumSchema extends Schema { @@ -31,4 +32,8 @@ export class EnumSchema extends Schema { ] return [] } + + override toTypeDefinitions() { + return this.value.map(val => new LiteralType(val)) + } } diff --git a/src/components/JSONSchema/ToTypes/Interface.ts b/src/components/JSONSchema/ToTypes/Interface.ts index 532e80738..2afb051f7 100644 --- a/src/components/JSONSchema/ToTypes/Interface.ts +++ b/src/components/JSONSchema/ToTypes/Interface.ts @@ -10,9 +10,9 @@ export class Interface extends Type { toString() { return `{ ${Object.entries(this.properties) - .map(([key, type]) => `\t${key}: ${type.toString()}`) + .map(([key, type]) => `${key}?: ${type.toString()}`) .join('\n')} [k: string]: any - }` + }\n` } } diff --git a/src/components/JSONSchema/ToTypes/Literal.ts b/src/components/JSONSchema/ToTypes/Literal.ts new file mode 100644 index 000000000..4dd4fd88e --- /dev/null +++ b/src/components/JSONSchema/ToTypes/Literal.ts @@ -0,0 +1,21 @@ +import { Type } from './Type' + +export class LiteralType extends Type { + constructor(protected literalType: string | number | boolean) { + super() + } + + static toTypeScriptType( + jsonSchemaType: 'boolean' | 'string' | 'decimal' | 'integer' | 'null' + ) { + if ((jsonSchemaType === 'decimal') | (type === 'integer')) + return 'number' + + return jsonSchemaType + } + + public toString() { + if (typeof this.literalType === 'string') return `'${this.literalType}'` + return this.literalType + } +} From 7cfe59346b1987e680ac4e27d6e3d644273881f2 Mon Sep 17 00:00:00 2001 From: solvedDev Date: Sun, 12 Jun 2022 20:53:17 +0200 Subject: [PATCH 4/6] upd: initial working generator --- src/components/Data/TypeLoader.ts | 15 +++++++++++++++ src/components/JSONSchema/Schema/Const.ts | 2 +- src/components/JSONSchema/Schema/ElseSchema.ts | 4 ++-- src/components/JSONSchema/Schema/Enum.ts | 4 +++- src/components/JSONSchema/Schema/Items.ts | 10 +++++----- src/components/JSONSchema/Schema/Parent.ts | 8 +++++--- src/components/JSONSchema/Schema/Properties.ts | 12 ++++++------ src/components/JSONSchema/Schema/Ref.ts | 4 ++-- src/components/JSONSchema/Schema/Schema.ts | 4 ++-- src/components/JSONSchema/Schema/ThenSchema.ts | 4 ++-- src/components/JSONSchema/Schema/Type.ts | 2 +- src/components/JSONSchema/ToTypes/Array.ts | 6 +++--- src/components/JSONSchema/ToTypes/Interface.ts | 17 +++++++---------- src/components/JSONSchema/ToTypes/Literal.ts | 15 +++------------ src/components/JSONSchema/ToTypes/Primitive.ts | 6 +++--- src/components/JSONSchema/ToTypes/Tuple.ts | 6 +++--- src/components/JSONSchema/ToTypes/Type.ts | 2 +- src/components/JSONSchema/ToTypes/Union.ts | 18 ++++++++++++++---- .../JSONSchema/requestOrCreateSchema.ts | 13 +++++++++++++ src/components/Projects/Project/Project.ts | 17 +++++++++++------ 20 files changed, 102 insertions(+), 67 deletions(-) create mode 100644 src/components/JSONSchema/requestOrCreateSchema.ts diff --git a/src/components/Data/TypeLoader.ts b/src/components/Data/TypeLoader.ts index 1ff647766..dd27d962e 100644 --- a/src/components/Data/TypeLoader.ts +++ b/src/components/Data/TypeLoader.ts @@ -6,6 +6,8 @@ import { getLatestFormatVersion } from './FormatVersions' import { DataLoader } from './DataLoader' import { Tab } from '../TabSystem/CommonTab' import { FileTab } from '../TabSystem/FileTab' +import { SchemaManager } from '../JSONSchema/Manager' +import { requestOrCreateSchema } from '../JSONSchema/requestOrCreateSchema' const types = new Map() @@ -59,6 +61,19 @@ export class TypeLoader { await App.fileType.ready.fired const { types = [] } = App.fileType.get(filePath) ?? {} + // console.log( + // App.fileType.all.filter( + // (fileType) => fileType.id === 'tradeTable' + // )[0]?.schema, + // requestOrCreateSchema( + // App.fileType.all.filter( + // (fileType) => fileType.id === 'tradeTable' + // )[0]?.schema + // ) + // ?.toTypeDefinition() + // .toString() + // ) + const libs = await Promise.all( types.map(async (type) => { if (typeof type === 'string') diff --git a/src/components/JSONSchema/Schema/Const.ts b/src/components/JSONSchema/Schema/Const.ts index 68ea1ac17..096ef3c6a 100644 --- a/src/components/JSONSchema/Schema/Const.ts +++ b/src/components/JSONSchema/Schema/Const.ts @@ -22,7 +22,7 @@ export class ConstSchema extends Schema { return [] } - override toTypeDefinitions() { + override toTypeDefinition() { return new LiteralType(this.value) } } diff --git a/src/components/JSONSchema/Schema/ElseSchema.ts b/src/components/JSONSchema/Schema/ElseSchema.ts index 082ecf10d..705eb5b37 100644 --- a/src/components/JSONSchema/Schema/ElseSchema.ts +++ b/src/components/JSONSchema/Schema/ElseSchema.ts @@ -39,7 +39,7 @@ export class ElseSchema extends Schema { return [] } - override toTypeDefinitions() { - return this.rootSchema.toTypeDefinitions() + override toTypeDefinition() { + return this.rootSchema.toTypeDefinition() } } diff --git a/src/components/JSONSchema/Schema/Enum.ts b/src/components/JSONSchema/Schema/Enum.ts index 6ab9c2ffd..57ff0b6bd 100644 --- a/src/components/JSONSchema/Schema/Enum.ts +++ b/src/components/JSONSchema/Schema/Enum.ts @@ -33,7 +33,9 @@ export class EnumSchema extends Schema { return [] } - override toTypeDefinitions() { + override toTypeDefinition() { + if(!Array.isArray(this.value)) return null + return this.value.map(val => new LiteralType(val)) } } diff --git a/src/components/JSONSchema/Schema/Items.ts b/src/components/JSONSchema/Schema/Items.ts index 8f751ca8b..37eaa43c5 100644 --- a/src/components/JSONSchema/Schema/Items.ts +++ b/src/components/JSONSchema/Schema/Items.ts @@ -1,6 +1,6 @@ import { RootSchema } from './Root' import { IDiagnostic, Schema } from './Schema' -import { Tuple } from '../ToTypes/Tuple' +import { TupleType } from '../ToTypes/Tuple' import { ArrayType } from '../ToTypes/Array' export class ItemsSchema extends Schema { @@ -70,15 +70,15 @@ export class ItemsSchema extends Schema { return [] } - override toTypeDefinitions() { + override toTypeDefinition() { if (Array.isArray(this.children)) { - return new Tuple( + return new TupleType( this.children - .map((child) => child.toTypeDefinitions()) + .map((child) => child.toTypeDefinition()) .filter((type) => type !== null) ) } else { - const type = this.children.toTypeDefinitions() + const type = this.children.toTypeDefinition() if (type === null) return null return new ArrayType(type) diff --git a/src/components/JSONSchema/Schema/Parent.ts b/src/components/JSONSchema/Schema/Parent.ts index 174b1f121..8aed1b0f2 100644 --- a/src/components/JSONSchema/Schema/Parent.ts +++ b/src/components/JSONSchema/Schema/Parent.ts @@ -1,3 +1,5 @@ +import { BaseType } from 'typescript' +import { UnionType } from '../ToTypes/Union' import { Schema } from './Schema' export abstract class ParentSchema extends Schema { @@ -31,10 +33,10 @@ export abstract class ParentSchema extends Schema { return children } - override toTypeDefinitions() { + override toTypeDefinition() { return new UnionType( - this.children - .map((child) => child.toTypeDefinitions()) + this.children + .map((child) => child.toTypeDefinition()) .filter((child) => child !== null) ) } diff --git a/src/components/JSONSchema/Schema/Properties.ts b/src/components/JSONSchema/Schema/Properties.ts index 732ad7775..951cc9c6a 100644 --- a/src/components/JSONSchema/Schema/Properties.ts +++ b/src/components/JSONSchema/Schema/Properties.ts @@ -1,6 +1,6 @@ import { RootSchema } from './Root' import { IDiagnostic, Schema } from './Schema' -import { Interface } from '../ToTypes/Interface' +import { InterfaceType } from '../ToTypes/Interface' export class PropertiesSchema extends Schema { protected children: Record = {} @@ -76,16 +76,16 @@ export class PropertiesSchema extends Schema { return diagnostics } - override toTypeDefinitions() { - const interface = new Interface() + override toTypeDefinition() { + const interfaceType = new InterfaceType() for (const [propertyName, child] of Object.entries(this.children)) { - const type = child.toTypeDefinitions() + const type = child.toTypeDefinition() if (type === null) continue - interface.addProperty(propertyName, type) + interfaceType.addProperty(propertyName, type) } - return interface + return interfaceType } } diff --git a/src/components/JSONSchema/Schema/Ref.ts b/src/components/JSONSchema/Schema/Ref.ts index 53a48adb9..5b9c4a797 100644 --- a/src/components/JSONSchema/Schema/Ref.ts +++ b/src/components/JSONSchema/Schema/Ref.ts @@ -75,7 +75,7 @@ export class RefSchema extends Schema { return this.rootSchema.getFreeIfSchema() } - override toTypeDefinitions() { - return this.rootSchema.toTypeDefinitions() + override toTypeDefinition() { + return this.rootSchema.toTypeDefinition() } } diff --git a/src/components/JSONSchema/Schema/Schema.ts b/src/components/JSONSchema/Schema/Schema.ts index 3e3481e5e..d1cba5540 100644 --- a/src/components/JSONSchema/Schema/Schema.ts +++ b/src/components/JSONSchema/Schema/Schema.ts @@ -1,4 +1,4 @@ -import { Type } from '../ToTypes/Type' +import { BaseType } from '../ToTypes/Type' export interface ISchemaResult { diagnostics: IDiagnostic[] @@ -45,7 +45,7 @@ export abstract class Schema { location: (string | number)[] ): Schema[] - toTypeDefinitions(): Type | null { + toTypeDefinition(): BaseType | null { return null } } diff --git a/src/components/JSONSchema/Schema/ThenSchema.ts b/src/components/JSONSchema/Schema/ThenSchema.ts index 90d9deb0e..a858dd041 100644 --- a/src/components/JSONSchema/Schema/ThenSchema.ts +++ b/src/components/JSONSchema/Schema/ThenSchema.ts @@ -39,7 +39,7 @@ export class ThenSchema extends Schema { return [] } - override toTypeDefinitions() { - return this.rootSchema.toTypeDefinitions() + override toTypeDefinition() { + return this.rootSchema.toTypeDefinition() } } diff --git a/src/components/JSONSchema/Schema/Type.ts b/src/components/JSONSchema/Schema/Type.ts index 75716b5a1..1298b9d47 100644 --- a/src/components/JSONSchema/Schema/Type.ts +++ b/src/components/JSONSchema/Schema/Type.ts @@ -63,7 +63,7 @@ export class TypeSchema extends Schema { return [] } - override toTypeDefinitions() { + override toTypeDefinition() { const values = ( Array.isArray(this.value) ? this.value : [this.value] ).filter((type) => !['object', 'array'].includes(type)) diff --git a/src/components/JSONSchema/ToTypes/Array.ts b/src/components/JSONSchema/ToTypes/Array.ts index 91a49599f..089a1c064 100644 --- a/src/components/JSONSchema/ToTypes/Array.ts +++ b/src/components/JSONSchema/ToTypes/Array.ts @@ -1,7 +1,7 @@ -import { Type } from './Type' +import { BaseType } from './Type' -export class ArrayType extends Type { - constructor(public readonly type: Type) { +export class ArrayType extends BaseType { + constructor(public readonly type: BaseType) { super() } diff --git a/src/components/JSONSchema/ToTypes/Interface.ts b/src/components/JSONSchema/ToTypes/Interface.ts index 2afb051f7..826228820 100644 --- a/src/components/JSONSchema/ToTypes/Interface.ts +++ b/src/components/JSONSchema/ToTypes/Interface.ts @@ -1,18 +1,15 @@ -import { Type } from './Type' +import { BaseType } from './Type' -export class Interface extends Type { - protected properties: Record = {} +export class InterfaceType extends BaseType { + protected properties: Record = {} - addProperty(name: string, type: Type) { + addProperty(name: string, type: BaseType) { this.properties[name] = type } toString() { - return `{ - ${Object.entries(this.properties) - .map(([key, type]) => `${key}?: ${type.toString()}`) - .join('\n')} - [k: string]: any - }\n` + return `{ ${Object.entries(this.properties) + .map(([key, type]) => `${key}?: ${type.toString()}`) + .join(';')}; }` } } diff --git a/src/components/JSONSchema/ToTypes/Literal.ts b/src/components/JSONSchema/ToTypes/Literal.ts index 4dd4fd88e..ff2230278 100644 --- a/src/components/JSONSchema/ToTypes/Literal.ts +++ b/src/components/JSONSchema/ToTypes/Literal.ts @@ -1,21 +1,12 @@ -import { Type } from './Type' +import { BaseType } from './Type' -export class LiteralType extends Type { +export class LiteralType extends BaseType { constructor(protected literalType: string | number | boolean) { super() } - static toTypeScriptType( - jsonSchemaType: 'boolean' | 'string' | 'decimal' | 'integer' | 'null' - ) { - if ((jsonSchemaType === 'decimal') | (type === 'integer')) - return 'number' - - return jsonSchemaType - } - public toString() { if (typeof this.literalType === 'string') return `'${this.literalType}'` - return this.literalType + return `${this.literalType}` } } diff --git a/src/components/JSONSchema/ToTypes/Primitive.ts b/src/components/JSONSchema/ToTypes/Primitive.ts index fb4866080..3d4ce29f8 100644 --- a/src/components/JSONSchema/ToTypes/Primitive.ts +++ b/src/components/JSONSchema/ToTypes/Primitive.ts @@ -1,8 +1,8 @@ -import { Type } from './Type' +import { BaseType } from './Type' export type TSupportedPrimitiveTypes = 'string' | 'number' | 'boolean' | 'null' -export class PrimitiveType extends Type { +export class PrimitiveType extends BaseType { constructor(protected primitiveType: TSupportedPrimitiveTypes) { super() } @@ -10,7 +10,7 @@ export class PrimitiveType extends Type { static toTypeScriptType( jsonSchemaType: 'boolean' | 'string' | 'decimal' | 'integer' | 'null' ) { - if ((jsonSchemaType === 'decimal') | (type === 'integer')) + if (jsonSchemaType === 'decimal' || jsonSchemaType === 'integer') return 'number' return jsonSchemaType diff --git a/src/components/JSONSchema/ToTypes/Tuple.ts b/src/components/JSONSchema/ToTypes/Tuple.ts index 4be4f0334..6bf29314b 100644 --- a/src/components/JSONSchema/ToTypes/Tuple.ts +++ b/src/components/JSONSchema/ToTypes/Tuple.ts @@ -1,7 +1,7 @@ -import { Type } from './Type' +import { BaseType } from './Type' -export class Tuple extends Type { - constructor(public readonly types: Type[]) { +export class TupleType extends BaseType { + constructor(public readonly types: BaseType[]) { super() } diff --git a/src/components/JSONSchema/ToTypes/Type.ts b/src/components/JSONSchema/ToTypes/Type.ts index 14a80c85b..afaf68cfd 100644 --- a/src/components/JSONSchema/ToTypes/Type.ts +++ b/src/components/JSONSchema/ToTypes/Type.ts @@ -1,3 +1,3 @@ -export abstract class Type { +export abstract class BaseType { public abstract toString(): string } diff --git a/src/components/JSONSchema/ToTypes/Union.ts b/src/components/JSONSchema/ToTypes/Union.ts index f41a224ba..11e20f8bf 100644 --- a/src/components/JSONSchema/ToTypes/Union.ts +++ b/src/components/JSONSchema/ToTypes/Union.ts @@ -1,9 +1,19 @@ -import { Type } from '../ToTypes/Type' +import { BaseType } from '../ToTypes/Type' -export class UnionType extends Type { - constructor(protected types: Type[]) {} +export class UnionType extends BaseType { + constructor(public readonly types: BaseType[]) { + super() + } + + flat(): BaseType[] { + return this.types + .map((type) => (type instanceof UnionType ? type.flat() : type)) + .flat(Infinity) + } toString() { - return this.types.map((type) => type.toString()).join(' | ') + return [...new Set(this.flat().map((type) => type.toString()))].join( + ' | ' + ) } } diff --git a/src/components/JSONSchema/requestOrCreateSchema.ts b/src/components/JSONSchema/requestOrCreateSchema.ts new file mode 100644 index 000000000..4514d0a62 --- /dev/null +++ b/src/components/JSONSchema/requestOrCreateSchema.ts @@ -0,0 +1,13 @@ +import { SchemaManager } from './Manager' +import { RootSchema } from './Schema/Root' + +export function requestOrCreateSchema(fileUri: string) { + let schema = SchemaManager.requestRootSchema(fileUri) + if (schema) return schema + + const schemaDef = SchemaManager.request(fileUri) + schema = new RootSchema(fileUri, '$global', schemaDef) + SchemaManager.addRootSchema(fileUri, schema) + + return schema +} diff --git a/src/components/Projects/Project/Project.ts b/src/components/Projects/Project/Project.ts index 6c4b99641..d97830b00 100644 --- a/src/components/Projects/Project/Project.ts +++ b/src/components/Projects/Project/Project.ts @@ -201,11 +201,6 @@ export abstract class Project { await this.extensionLoader.loadExtensions() - const selectedTab = this.tabSystem?.selectedTab - this.typeLoader.activate( - selectedTab instanceof FileTab ? selectedTab.getPath() : undefined - ) - // Data needs to be loaded into IndexedDB before the PackIndexer can be used await this.app.dataLoader.fired @@ -218,8 +213,18 @@ export abstract class Project { const autoFetchChangedFiles = settingsState.compiler?.autoFetchChangedFiles ?? true + const selectedTab = this.tabSystem?.selectedTab + await Promise.all([ - this.jsonDefaults.activate(), + this.jsonDefaults + .activate() + .finally(() => + this.typeLoader.activate( + selectedTab instanceof FileTab + ? selectedTab.getPath() + : undefined + ) + ), autoFetchChangedFiles ? this.compilerService.start(changedFiles, deletedFiles) : Promise.resolve(), From 0c57272469b18e0aa8cfda028e630daea449563c Mon Sep 17 00:00:00 2001 From: solvedDev Date: Mon, 13 Jun 2022 12:38:22 +0200 Subject: [PATCH 5/6] upd: progress --- src/components/Data/TypeLoader.ts | 12 +--- src/components/JSONSchema/Schema/Const.ts | 3 +- .../JSONSchema/Schema/ElseSchema.ts | 4 +- src/components/JSONSchema/Schema/Enum.ts | 3 +- src/components/JSONSchema/Schema/Items.ts | 9 +-- src/components/JSONSchema/Schema/Parent.ts | 10 +-- .../JSONSchema/Schema/Properties.ts | 4 +- src/components/JSONSchema/Schema/Ref.ts | 22 +++++- src/components/JSONSchema/Schema/Schema.ts | 18 ++++- .../JSONSchema/Schema/ThenSchema.ts | 4 +- .../JSONSchema/ToTypes/CombinedType.ts | 71 +++++++++++++++++++ .../JSONSchema/ToTypes/Interface.ts | 22 +++++- .../JSONSchema/ToTypes/Intersection.ts | 12 ++++ .../JSONSchema/ToTypes/Primitive.ts | 2 +- src/components/JSONSchema/ToTypes/Type.ts | 4 ++ src/components/JSONSchema/ToTypes/Union.ts | 19 ++--- src/components/JSONSchema/ToTypes/main.ts | 22 ++++++ src/components/JSONSchema/pathToName.ts | 13 ++++ 18 files changed, 208 insertions(+), 46 deletions(-) create mode 100644 src/components/JSONSchema/ToTypes/CombinedType.ts create mode 100644 src/components/JSONSchema/ToTypes/Intersection.ts create mode 100644 src/components/JSONSchema/ToTypes/main.ts create mode 100644 src/components/JSONSchema/pathToName.ts diff --git a/src/components/Data/TypeLoader.ts b/src/components/Data/TypeLoader.ts index dd27d962e..7989afd91 100644 --- a/src/components/Data/TypeLoader.ts +++ b/src/components/Data/TypeLoader.ts @@ -6,8 +6,7 @@ import { getLatestFormatVersion } from './FormatVersions' import { DataLoader } from './DataLoader' import { Tab } from '../TabSystem/CommonTab' import { FileTab } from '../TabSystem/FileTab' -import { SchemaManager } from '../JSONSchema/Manager' -import { requestOrCreateSchema } from '../JSONSchema/requestOrCreateSchema' +import { toTypeDefinition } from '../JSONSchema/ToTypes/main' const types = new Map() @@ -62,16 +61,11 @@ export class TypeLoader { const { types = [] } = App.fileType.get(filePath) ?? {} // console.log( - // App.fileType.all.filter( - // (fileType) => fileType.id === 'tradeTable' - // )[0]?.schema, - // requestOrCreateSchema( + // ...toTypeDefinition( // App.fileType.all.filter( - // (fileType) => fileType.id === 'tradeTable' + // (fileType) => fileType.id === 'lootTable' // )[0]?.schema // ) - // ?.toTypeDefinition() - // .toString() // ) const libs = await Promise.all( diff --git a/src/components/JSONSchema/Schema/Const.ts b/src/components/JSONSchema/Schema/Const.ts index 096ef3c6a..8e6456f95 100644 --- a/src/components/JSONSchema/Schema/Const.ts +++ b/src/components/JSONSchema/Schema/Const.ts @@ -2,6 +2,7 @@ import { LiteralType } from '../ToTypes/Literal' import { Schema } from './Schema' export class ConstSchema extends Schema { + public readonly types = [] getSchemasFor() { return [] } @@ -23,6 +24,6 @@ export class ConstSchema extends Schema { } override toTypeDefinition() { - return new LiteralType(this.value) + return new LiteralType(this.value) } } diff --git a/src/components/JSONSchema/Schema/ElseSchema.ts b/src/components/JSONSchema/Schema/ElseSchema.ts index 705eb5b37..bc79a6478 100644 --- a/src/components/JSONSchema/Schema/ElseSchema.ts +++ b/src/components/JSONSchema/Schema/ElseSchema.ts @@ -39,7 +39,7 @@ export class ElseSchema extends Schema { return [] } - override toTypeDefinition() { - return this.rootSchema.toTypeDefinition() + override toTypeDefinition(hoisted: Set) { + return this.rootSchema.toTypeDefinition(hoisted) } } diff --git a/src/components/JSONSchema/Schema/Enum.ts b/src/components/JSONSchema/Schema/Enum.ts index 57ff0b6bd..73b51023b 100644 --- a/src/components/JSONSchema/Schema/Enum.ts +++ b/src/components/JSONSchema/Schema/Enum.ts @@ -1,4 +1,5 @@ import { LiteralType } from '../ToTypes/Literal' +import { UnionType } from '../ToTypes/Union' import { Schema } from './Schema' export class EnumSchema extends Schema { @@ -36,6 +37,6 @@ export class EnumSchema extends Schema { override toTypeDefinition() { if(!Array.isArray(this.value)) return null - return this.value.map(val => new LiteralType(val)) + return new UnionType(this.value.map(val => new LiteralType(val))) } } diff --git a/src/components/JSONSchema/Schema/Items.ts b/src/components/JSONSchema/Schema/Items.ts index 37eaa43c5..e8d1d4360 100644 --- a/src/components/JSONSchema/Schema/Items.ts +++ b/src/components/JSONSchema/Schema/Items.ts @@ -2,6 +2,7 @@ import { RootSchema } from './Root' import { IDiagnostic, Schema } from './Schema' import { TupleType } from '../ToTypes/Tuple' import { ArrayType } from '../ToTypes/Array' +import { BaseType } from '../ToTypes/Type' export class ItemsSchema extends Schema { protected children: Schema | Schema[] @@ -70,15 +71,15 @@ export class ItemsSchema extends Schema { return [] } - override toTypeDefinition() { + override toTypeDefinition(hoisted: Set) { if (Array.isArray(this.children)) { return new TupleType( - this.children - .map((child) => child.toTypeDefinition()) + this.children + .map((child) => child.toTypeDefinition(hoisted)) .filter((type) => type !== null) ) } else { - const type = this.children.toTypeDefinition() + const type = this.children.toTypeDefinition(hoisted) if (type === null) return null return new ArrayType(type) diff --git a/src/components/JSONSchema/Schema/Parent.ts b/src/components/JSONSchema/Schema/Parent.ts index 8aed1b0f2..2476ca181 100644 --- a/src/components/JSONSchema/Schema/Parent.ts +++ b/src/components/JSONSchema/Schema/Parent.ts @@ -1,4 +1,4 @@ -import { BaseType } from 'typescript' +import { BaseType } from '../ToTypes/Type' import { UnionType } from '../ToTypes/Union' import { Schema } from './Schema' @@ -33,11 +33,11 @@ export abstract class ParentSchema extends Schema { return children } - override toTypeDefinition() { + override toTypeDefinition(hoisted: Set) { return new UnionType( - this.children - .map((child) => child.toTypeDefinition()) - .filter((child) => child !== null) + (this.children + .map((child) => child.toTypeDefinition(hoisted)) + .filter((schema) => schema !== null)) ) } } diff --git a/src/components/JSONSchema/Schema/Properties.ts b/src/components/JSONSchema/Schema/Properties.ts index 951cc9c6a..65889c10e 100644 --- a/src/components/JSONSchema/Schema/Properties.ts +++ b/src/components/JSONSchema/Schema/Properties.ts @@ -76,11 +76,11 @@ export class PropertiesSchema extends Schema { return diagnostics } - override toTypeDefinition() { + override toTypeDefinition(hoisted: Set) { const interfaceType = new InterfaceType() for (const [propertyName, child] of Object.entries(this.children)) { - const type = child.toTypeDefinition() + const type = child.toTypeDefinition(hoisted) if (type === null) continue interfaceType.addProperty(propertyName, type) diff --git a/src/components/JSONSchema/Schema/Ref.ts b/src/components/JSONSchema/Schema/Ref.ts index 5b9c4a797..e4bbdb336 100644 --- a/src/components/JSONSchema/Schema/Ref.ts +++ b/src/components/JSONSchema/Schema/Ref.ts @@ -1,7 +1,9 @@ import { SchemaManager } from '../Manager' +import { pathToName } from '../pathToName' +import { PrimitiveType } from '../ToTypes/Primitive' import { RootSchema } from './Root' import { Schema } from './Schema' -import { dirname, join } from '/@/utils/path' +import { dirname, join, relative } from '/@/utils/path' export class RefSchema extends Schema { public readonly schemaType = 'refSchema' @@ -75,7 +77,21 @@ export class RefSchema extends Schema { return this.rootSchema.getFreeIfSchema() } - override toTypeDefinition() { - return this.rootSchema.toTypeDefinition() + getName() { + return pathToName( + relative( + 'file:///data/packages/minecraftBedrock/schema', + this.rootSchema.getLocation() + ) + ) + } + + override toTypeDefinition(hoisted: Set, forceEval?: boolean) { + if(forceEval) return this.rootSchema.toTypeDefinition(hoisted) + + if(!hoisted.has(this)) + hoisted.add(this) + + return new PrimitiveType(this.getName()) } } diff --git a/src/components/JSONSchema/Schema/Schema.ts b/src/components/JSONSchema/Schema/Schema.ts index d1cba5540..875efb4af 100644 --- a/src/components/JSONSchema/Schema/Schema.ts +++ b/src/components/JSONSchema/Schema/Schema.ts @@ -1,4 +1,6 @@ +import { pathToName } from '../pathToName' import { BaseType } from '../ToTypes/Type' +import { relative } from '/@/utils/path' export interface ISchemaResult { diagnostics: IDiagnostic[] @@ -45,7 +47,21 @@ export abstract class Schema { location: (string | number)[] ): Schema[] - toTypeDefinition(): BaseType | null { + toTypeDefinition( + hoisted: Set, + forceEval?: boolean + ): BaseType | null { return null } + getName() { + return pathToName( + relative( + 'file:///data/packages/minecraftBedrock/schema', + this.location + ) + ) + } + getLocation() { + return this.location + } } diff --git a/src/components/JSONSchema/Schema/ThenSchema.ts b/src/components/JSONSchema/Schema/ThenSchema.ts index a858dd041..ee1aa9cdd 100644 --- a/src/components/JSONSchema/Schema/ThenSchema.ts +++ b/src/components/JSONSchema/Schema/ThenSchema.ts @@ -39,7 +39,7 @@ export class ThenSchema extends Schema { return [] } - override toTypeDefinition() { - return this.rootSchema.toTypeDefinition() + override toTypeDefinition(hoisted: Set) { + return this.rootSchema.toTypeDefinition(hoisted) } } diff --git a/src/components/JSONSchema/ToTypes/CombinedType.ts b/src/components/JSONSchema/ToTypes/CombinedType.ts new file mode 100644 index 000000000..65f5747e6 --- /dev/null +++ b/src/components/JSONSchema/ToTypes/CombinedType.ts @@ -0,0 +1,71 @@ +import { InterfaceType } from './Interface' +import { BaseType } from './Type' + +export abstract class CombinedType extends BaseType { + constructor(private types: BaseType[], protected joinChar: string) { + super() + } + + protected abstract isOfThisType(type: CombinedType): boolean + + add(baseType: BaseType) { + this.types.push(baseType) + } + + protected flatten(): BaseType[] { + return this.types + .map((type) => { + if (type instanceof CombinedType) { + const flat = type.flatten() + + if (flat.length === 0) return [] + else if (flat.length === 1) return flat[0] + else if (this.isOfThisType(type)) return flat + + return type + } else return type + }) + .flat(1) + } + + protected withCollapsedInterfaces() { + const types = this.flatten() + const interfaceType = new InterfaceType() + + const newTypes: BaseType[] = [] + let foundInterface = false + for (const type of types) { + if (type instanceof InterfaceType) { + interfaceType.addFrom(type) + foundInterface = true + } else { + newTypes.push(type) + } + } + + return foundInterface ? newTypes.concat(interfaceType) : newTypes + } + + isStringCollection(collection: string[]) { + return collection.every( + (type) => + (type.startsWith("'") && type.endsWith("'")) || + type === 'string' + ) + } + + toString() { + let collection = [ + ...new Set( + this.withCollapsedInterfaces().map((type) => type.toString()) + ), + ] + + if (this.isStringCollection(collection)) + collection = collection.filter((type) => type !== 'string') + + if (collection.length === 1) return collection[0] + + return `(${collection.join(this.joinChar)})` + } +} diff --git a/src/components/JSONSchema/ToTypes/Interface.ts b/src/components/JSONSchema/ToTypes/Interface.ts index 826228820..0403bd71e 100644 --- a/src/components/JSONSchema/ToTypes/Interface.ts +++ b/src/components/JSONSchema/ToTypes/Interface.ts @@ -1,4 +1,6 @@ +import { CombinedType } from './CombinedType' import { BaseType } from './Type' +import { UnionType } from './Union' export class InterfaceType extends BaseType { protected properties: Record = {} @@ -6,10 +8,26 @@ export class InterfaceType extends BaseType { addProperty(name: string, type: BaseType) { this.properties[name] = type } + addFrom(interfaceType: InterfaceType) { + for (const [key, type] of Object.entries(interfaceType.properties)) { + const existingType = this.properties[key] + if(existingType instanceof CombinedType) { + existingType.add(type) + } else if(existingType) { + this.addProperty(key, new UnionType([this.properties[key], type])) + } else { + this.addProperty(key, type) + } + } + } toString() { return `{ ${Object.entries(this.properties) .map(([key, type]) => `${key}?: ${type.toString()}`) - .join(';')}; }` + .join(';')};[k: string]: unknown; }` + } + + override withName(name: string) { + return `interface ${name} ${this.toString()};` } -} +} \ No newline at end of file diff --git a/src/components/JSONSchema/ToTypes/Intersection.ts b/src/components/JSONSchema/ToTypes/Intersection.ts new file mode 100644 index 000000000..7bdc41882 --- /dev/null +++ b/src/components/JSONSchema/ToTypes/Intersection.ts @@ -0,0 +1,12 @@ +import { BaseType } from './Type' +import { CombinedType } from './CombinedType' + +export class IntersectionType extends CombinedType { + constructor(types: BaseType[]) { + super(types, ' & ') + } + + isOfThisType(type: CombinedType) { + return type instanceof IntersectionType + } +} diff --git a/src/components/JSONSchema/ToTypes/Primitive.ts b/src/components/JSONSchema/ToTypes/Primitive.ts index 3d4ce29f8..883ce49fc 100644 --- a/src/components/JSONSchema/ToTypes/Primitive.ts +++ b/src/components/JSONSchema/ToTypes/Primitive.ts @@ -3,7 +3,7 @@ import { BaseType } from './Type' export type TSupportedPrimitiveTypes = 'string' | 'number' | 'boolean' | 'null' export class PrimitiveType extends BaseType { - constructor(protected primitiveType: TSupportedPrimitiveTypes) { + constructor(protected primitiveType: TSupportedPrimitiveTypes | string) { super() } diff --git a/src/components/JSONSchema/ToTypes/Type.ts b/src/components/JSONSchema/ToTypes/Type.ts index afaf68cfd..58035b296 100644 --- a/src/components/JSONSchema/ToTypes/Type.ts +++ b/src/components/JSONSchema/ToTypes/Type.ts @@ -1,3 +1,7 @@ export abstract class BaseType { public abstract toString(): string + + withName(name: string) { + return `type ${name} = ${this.toString()};` + } } diff --git a/src/components/JSONSchema/ToTypes/Union.ts b/src/components/JSONSchema/ToTypes/Union.ts index 11e20f8bf..79dc240e4 100644 --- a/src/components/JSONSchema/ToTypes/Union.ts +++ b/src/components/JSONSchema/ToTypes/Union.ts @@ -1,19 +1,12 @@ import { BaseType } from '../ToTypes/Type' +import { CombinedType } from './CombinedType' -export class UnionType extends BaseType { - constructor(public readonly types: BaseType[]) { - super() +export class UnionType extends CombinedType { + constructor(types: BaseType[]) { + super(types, ' | ') } - flat(): BaseType[] { - return this.types - .map((type) => (type instanceof UnionType ? type.flat() : type)) - .flat(Infinity) - } - - toString() { - return [...new Set(this.flat().map((type) => type.toString()))].join( - ' | ' - ) + isOfThisType(type: CombinedType) { + return type instanceof UnionType } } diff --git a/src/components/JSONSchema/ToTypes/main.ts b/src/components/JSONSchema/ToTypes/main.ts new file mode 100644 index 000000000..b1b80ca28 --- /dev/null +++ b/src/components/JSONSchema/ToTypes/main.ts @@ -0,0 +1,22 @@ +import { requestOrCreateSchema } from '../requestOrCreateSchema' +import { Schema } from '../Schema/Schema' + +export function toTypeDefinition(fileUri: string): [string, string] { + const hoisted = new Set() + + const definition = requestOrCreateSchema(fileUri) + ?.toTypeDefinition(hoisted) + .toString() + + let hoistedDefinitions = new Set() + + for (const schema of hoisted) { + hoistedDefinitions.add( + schema.toTypeDefinition(hoisted, true)?.withName(schema.getName()) + ) + + console.log(schema.getName(), schema.toTypeDefinition(hoisted, true)) + } + + return [[...hoistedDefinitions].join(''), definition] +} diff --git a/src/components/JSONSchema/pathToName.ts b/src/components/JSONSchema/pathToName.ts new file mode 100644 index 000000000..b1e890511 --- /dev/null +++ b/src/components/JSONSchema/pathToName.ts @@ -0,0 +1,13 @@ +export function pathToName(path: string): string { + const parts = path.replaceAll('#', '').replaceAll('_', '/').split(/\\|\//g) + + // Capitalize the first letter of each part + const capitalized = parts.map( + (part) => part.charAt(0).toUpperCase() + part.slice(1) + ) + + // Remove file extensions from parts (they can be anywhere because of the "#/" $ref hash syntax) + const withoutExts = capitalized.map((part) => part.split('.')[0]) + + return withoutExts.join('') +} From 3d90ece58620e3a440086b275391b4b644170d1a Mon Sep 17 00:00:00 2001 From: solvedDev Date: Thu, 16 Jun 2022 21:14:59 +0200 Subject: [PATCH 6/6] feat: support "doNotSuggest" --- src/components/JSONSchema/Schema/Items.ts | 3 +++ src/components/JSONSchema/Schema/Parent.ts | 2 ++ src/components/JSONSchema/Schema/Properties.ts | 2 ++ 3 files changed, 7 insertions(+) diff --git a/src/components/JSONSchema/Schema/Items.ts b/src/components/JSONSchema/Schema/Items.ts index 7c32ec925..ca1b133c1 100644 --- a/src/components/JSONSchema/Schema/Items.ts +++ b/src/components/JSONSchema/Schema/Items.ts @@ -76,10 +76,13 @@ export class ItemsSchema extends Schema { if (Array.isArray(this.children)) { return new TupleType( this.children + .filter((child) => !child.hasDoNotSuggest) .map((child) => child.toTypeDefinition(hoisted)) .filter((type) => type !== null) ) } else { + if(this.children.hasDoNotSuggest) return null + const type = this.children.toTypeDefinition(hoisted) if (type === null) return null diff --git a/src/components/JSONSchema/Schema/Parent.ts b/src/components/JSONSchema/Schema/Parent.ts index 1fd29faa5..26bd6276a 100644 --- a/src/components/JSONSchema/Schema/Parent.ts +++ b/src/components/JSONSchema/Schema/Parent.ts @@ -43,6 +43,8 @@ export abstract class ParentSchema extends Schema { } override toTypeDefinition(hoisted: Set) { + if(this.hasDoNotSuggest) console.warn(`[${this.location}] Called Schema.toTypeDefinition on a schema which has "doNotSuggest"`) + return new UnionType( (this.children .map((child) => child.toTypeDefinition(hoisted)) diff --git a/src/components/JSONSchema/Schema/Properties.ts b/src/components/JSONSchema/Schema/Properties.ts index 8fd8acf4a..9213ef4e3 100644 --- a/src/components/JSONSchema/Schema/Properties.ts +++ b/src/components/JSONSchema/Schema/Properties.ts @@ -87,6 +87,8 @@ export class PropertiesSchema extends Schema { const interfaceType = new InterfaceType() for (const [propertyName, child] of Object.entries(this.children)) { + if(child.hasDoNotSuggest) continue + const type = child.toTypeDefinition(hoisted) if (type === null) continue