From 775043cffd21391ed5b38b1a69690932481e01ea Mon Sep 17 00:00:00 2001 From: nicosammito Date: Fri, 22 May 2026 23:04:42 +0200 Subject: [PATCH 1/2] feat: implement getTypeSchema function to generate schema from TypeScript type strings --- src/index.ts | 1 + src/schema/getTypeSchema.ts | 42 +++++++++++++++++++++++++++++++++++++ src/util/schema.util.ts | 31 +++++++++++++-------------- 3 files changed, 57 insertions(+), 17 deletions(-) create mode 100644 src/schema/getTypeSchema.ts diff --git a/src/index.ts b/src/index.ts index 446c232..97c43c3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,3 +3,4 @@ export * from './extraction/getValueFromType'; export * from './validation/getFlowValidation'; export * from './validation/getValueValidation'; export * from './schema/getSignatureSchema'; +export * from './schema/getTypeSchema'; diff --git a/src/schema/getTypeSchema.ts b/src/schema/getTypeSchema.ts new file mode 100644 index 0000000..f8aaafd --- /dev/null +++ b/src/schema/getTypeSchema.ts @@ -0,0 +1,42 @@ +import {DataType} from "@code0-tech/sagittarius-graphql-types" +import ts from "typescript" +import {getSchema, Schema} from "../util/schema.util" +import {createCompilerHost, getSharedTypeDeclarations} from "../utils" + +/** + * Generates a schema for a given TypeScript type string. + * + * This function creates a virtual TypeScript environment, parses the provided type string + * (along with any provided data type definitions), and extracts the schema for the last + * type-related statement (TypeAlias, Interface, or Class) found in the string. + * + * @param typeString - The TypeScript code containing the type definition (e.g., "type MyType = { a: string }"). + * @param dataTypes - An optional array of additional data type definitions to be included in the environment. + * @returns The generated Schema for the identified type, or undefined if no valid type was found or an error occurred. + */ +export const getTypeSchema = ( + typeString: string, + dataTypes: DataType[] = [], +): Schema | undefined => { + const fileName = "index.ts" + const typeDefs = getSharedTypeDeclarations(dataTypes) + const sourceCode = `${typeDefs}\n${typeString}` + + const host = createCompilerHost(fileName, sourceCode) + const program = host.languageService.getProgram() + const sourceFile = program?.getSourceFile(fileName) + const checker = program?.getTypeChecker() + + if (!sourceFile || !checker) return undefined + + const targetStatement = sourceFile.statements + .filter((stmt): stmt is ts.TypeAliasDeclaration | ts.InterfaceDeclaration | ts.ClassDeclaration => + ts.isTypeAliasDeclaration(stmt) || ts.isInterfaceDeclaration(stmt) || ts.isClassDeclaration(stmt) + ).pop() + if (!targetStatement) return undefined + + const targetType = checker.getTypeAtLocation(targetStatement) + if (!targetType) return undefined + + return getSchema(checker, undefined, targetType, [], [], false) +} diff --git a/src/util/schema.util.ts b/src/util/schema.util.ts index 827b065..a7d25ca 100644 --- a/src/util/schema.util.ts +++ b/src/util/schema.util.ts @@ -113,31 +113,28 @@ export type Schema = */ export const getSchema = ( checker: ts.TypeChecker, - node: ts.VariableDeclaration, + node: ts.VariableDeclaration | undefined, parameterType: ts.Type, functionDeclarations: FunctionDeclaration[], functions: FunctionDefinition[], suggestions: boolean = true ): Schema => { // Collect all available suggestions for this parameter - const literalValueSuggestions = getValues(parameterType); - const referenceSuggestions = getReferences( - checker, - node!, - parameterType, - checker.getSymbolsInScope(node!, ts.SymbolFlags.Variable) - ); - const nodeSuggestions = getNodes( - checker, - functionDeclarations, - functions, - parameterType - ); const combinedSuggestions = suggestions ? { suggestions: [ - ...literalValueSuggestions, - ...referenceSuggestions, - ...nodeSuggestions, + ...getValues(parameterType), + ...(node ? getReferences( + checker, + node, + parameterType, + checker.getSymbolsInScope(node, ts.SymbolFlags.Variable) + ) : []), + ...getNodes( + checker, + functionDeclarations, + functions, + parameterType + ), ], } : {}; From 433991ca329390168ca0155744840da20aa1bbb7 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Fri, 22 May 2026 23:51:31 +0200 Subject: [PATCH 2/2] feat: enhance getTypeSchema to handle TypeScript type expressions and update documentation --- src/schema/getTypeSchema.ts | 11 +++++------ test/schema/schema.test.ts | 8 +++++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/schema/getTypeSchema.ts b/src/schema/getTypeSchema.ts index f8aaafd..763306d 100644 --- a/src/schema/getTypeSchema.ts +++ b/src/schema/getTypeSchema.ts @@ -4,13 +4,12 @@ import {getSchema, Schema} from "../util/schema.util" import {createCompilerHost, getSharedTypeDeclarations} from "../utils" /** - * Generates a schema for a given TypeScript type string. + * Generates a schema for a given TypeScript type expression string. * - * This function creates a virtual TypeScript environment, parses the provided type string - * (along with any provided data type definitions), and extracts the schema for the last - * type-related statement (TypeAlias, Interface, or Class) found in the string. + * This function creates a virtual TypeScript environment, wraps the provided type expression + * into a type alias 'T', and extracts the schema for it. * - * @param typeString - The TypeScript code containing the type definition (e.g., "type MyType = { a: string }"). + * @param typeString - The TypeScript type expression (e.g., "string | number" or "{ a: string }"). * @param dataTypes - An optional array of additional data type definitions to be included in the environment. * @returns The generated Schema for the identified type, or undefined if no valid type was found or an error occurred. */ @@ -20,7 +19,7 @@ export const getTypeSchema = ( ): Schema | undefined => { const fileName = "index.ts" const typeDefs = getSharedTypeDeclarations(dataTypes) - const sourceCode = `${typeDefs}\n${typeString}` + const sourceCode = `${typeDefs}\ntype MyType = ${typeString}` const host = createCompilerHost(fileName, sourceCode) const program = host.languageService.getProgram() diff --git a/test/schema/schema.test.ts b/test/schema/schema.test.ts index fc10904..a082e31 100644 --- a/test/schema/schema.test.ts +++ b/test/schema/schema.test.ts @@ -1,6 +1,6 @@ import {describe, expect, it} from "vitest"; import {Flow} from "@code0-tech/sagittarius-graphql-types"; -import {getFlowValidation, getSignatureSchema} from "../../src"; +import {getFlowValidation, getSignatureSchema, getTypeSchema} from "../../src"; import {DATA_TYPES, FUNCTION_SIGNATURES} from "../data"; describe("Schema", () => { @@ -116,4 +116,10 @@ describe("Schema", () => { }); + it('3', () => { + const result = getTypeSchema("{text: NUMBER, bla?: LIST}", DATA_TYPES); + + //console.dir(result, {depth: null}) + }); + }) \ No newline at end of file