UNPKG

typescript-runtime-schemas

Version:

A TypeScript schema generation tool that extracts Zod schemas from TypeScript source files with runtime validation support. Generate validation schemas directly from your existing TypeScript types with support for computed types and constraint-based valid

838 lines 34.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TypeResolver = void 0; exports.resolveTypesFromSource = resolveTypesFromSource; exports.getResolvedType = getResolvedType; exports.resolveTypesFromInput = resolveTypesFromInput; exports.getResolvedTypeFromInput = getResolvedTypeFromInput; exports.resolveTypesFromDirectory = resolveTypesFromDirectory; exports.resolveTypesFromGlob = resolveTypesFromGlob; exports.resolveTypesFromFile = resolveTypesFromFile; exports.getResolvedTypeFromFile = getResolvedTypeFromFile; exports.getResolvedTypeFromDirectory = getResolvedTypeFromDirectory; const ts_morph_1 = require("ts-morph"); /** * TypeScript type resolver that can resolve computed types like Pick, Omit, etc. using ts-morph */ class TypeResolver { constructor(sourceCode, compilerOptions) { // Create a new ts-morph project this.project = new ts_morph_1.Project({ compilerOptions: compilerOptions || { target: ts_morph_1.ScriptTarget.ES2020, module: ts_morph_1.ModuleKind.CommonJS, strict: true, }, useInMemoryFileSystem: true, }); // Create a virtual source file const sourceFile = this.project.createSourceFile("temp.ts", sourceCode); this.sourceFiles = [sourceFile]; } /** * Create TypeResolver from an existing ts-morph project with multiple files */ static fromProject(project, sourceFiles) { const resolver = Object.create(TypeResolver.prototype); resolver.project = project; resolver.sourceFiles = sourceFiles; return resolver; } /** * Get the primary source file (for backward compatibility) */ get sourceFile() { return this.sourceFiles[0]; } /** * Resolve all type aliases in the source code to their computed forms * @param predicate Optional function to filter which types should be resolved. * Types for which the predicate returns false will be returned as-is. */ resolveTypes(predicate) { const resolvedDeclarations = []; // Process all source files for (const sourceFile of this.sourceFiles) { // Process interfaces first (they don't need resolution, just include them) const interfaces = sourceFile.getInterfaces(); for (const interfaceDecl of interfaces) { const interfaceName = interfaceDecl.getName(); resolvedDeclarations.push(`type ${interfaceName} = ${this.resolveInterfaceDeclaration(interfaceDecl)}`); } // Process type aliases const typeAliases = sourceFile.getTypeAliases(); for (const typeAlias of typeAliases) { const typeName = typeAlias.getName(); // If no predicate or predicate returns true, resolve the type if (!predicate || predicate(typeName, typeAlias)) { const resolvedType = this.resolveTypeAlias(typeAlias); resolvedDeclarations.push(`type ${typeName} = ${resolvedType}`); } else { // If predicate returns false, return original declaration const originalDeclaration = typeAlias.getText(); resolvedDeclarations.push(originalDeclaration); } } } return resolvedDeclarations.join("\n"); } /** * Get a specific resolved type by name (searches all files) */ getResolvedType(typeName) { // Search through all source files for type aliases for (const sourceFile of this.sourceFiles) { const typeAlias = sourceFile.getTypeAlias(typeName); if (typeAlias) { return this.resolveTypeAlias(typeAlias); } } // Search through all source files for interfaces for (const sourceFile of this.sourceFiles) { const interfaceDecl = sourceFile.getInterface(typeName); if (interfaceDecl) { return this.resolveInterfaceDeclaration(interfaceDecl); } } throw new Error(`Type ${typeName} not found in any source file`); } /** * Resolve a specific type alias to its computed form */ resolveTypeAlias(typeAlias) { const typeNode = typeAlias.getTypeNode(); if (!typeNode) { throw new Error("Type alias has no type node"); } return this.resolveTypeNode(typeNode); } /** * Resolve an interface declaration to its type literal form */ resolveInterfaceDeclaration(interfaceDecl) { const properties = []; for (const member of interfaceDecl.getMembers()) { // Use Node.isPropertySignature instead of magic number if (member.getKind() === 167 || member.getName) { // PropertySignature const name = member.getName ? member.getName() : null; const typeNode = member.getTypeNode ? member.getTypeNode() : null; const isOptional = member.hasQuestionToken ? member.hasQuestionToken() : false; if (name && typeNode) { const optionalMarker = isOptional ? "?" : ""; const typeText = this.resolveTypeNode(typeNode); properties.push(`${name}${optionalMarker}: ${typeText}`); } } } return `{ ${properties.join("; ")} }`; } /** * Resolve a type node to its string representation */ resolveTypeNode(typeNode) { // Handle type references (like Pick<User, 'name'>) if (ts_morph_1.Node.isTypeReference(typeNode)) { return this.resolveTypeReference(typeNode); } // Handle type literals (like { id: number; name: string; }) if (ts_morph_1.Node.isTypeLiteral(typeNode)) { return this.resolveTypeLiteral(typeNode); } // Handle intersection types (like User & { role: Role }) if (ts_morph_1.Node.isIntersectionTypeNode(typeNode)) { return this.resolveIntersectionType(typeNode); } // Handle union types (like string | number) if (ts_morph_1.Node.isUnionTypeNode(typeNode)) { return this.resolveUnionType(typeNode); } // For other types, return the text representation return typeNode.getText(); } /** * Resolve type references like Pick<User, 'name' | 'email'> */ resolveTypeReference(typeRef) { if (!ts_morph_1.Node.isTypeReference(typeRef)) { return typeRef.getText(); } const typeName = typeRef.getTypeName().getText(); const typeArgs = typeRef.getTypeArguments(); // Handle utility types with key selection if ((typeName === "Pick" || typeName === "Omit") && typeArgs.length >= 2) { return this.resolveUtilityType(typeName, typeArgs); } // Handle single-argument utility types if ((typeName === "Partial" || typeName === "Required" || typeName === "Readonly" || typeName === "NonNullable") && typeArgs.length >= 1) { return this.resolveSingleArgUtilityType(typeName, typeArgs[0]); } // Handle Record<K, V> if (typeName === "Record" && typeArgs.length >= 2) { return this.resolveRecordType(typeArgs[0], typeArgs[1]); } // Handle Exclude<T, U> and Extract<T, U> if ((typeName === "Exclude" || typeName === "Extract") && typeArgs.length >= 2) { return this.resolveExcludeExtractType(typeName, typeArgs[0], typeArgs[1]); } // Handle ReturnType<T> if (typeName === "ReturnType" && typeArgs.length >= 1) { return this.resolveReturnType(typeArgs[0]); } // Handle Parameters<T> if (typeName === "Parameters" && typeArgs.length >= 1) { return this.resolveParametersType(typeArgs[0]); } // Handle ConstructorParameters<T> if (typeName === "ConstructorParameters" && typeArgs.length >= 1) { return this.resolveConstructorParametersType(typeArgs[0]); } // Handle InstanceType<T> if (typeName === "InstanceType" && typeArgs.length >= 1) { return this.resolveInstanceType(typeArgs[0]); } // Handle ThisParameterType<T> and OmitThisParameter<T> if ((typeName === "ThisParameterType" || typeName === "OmitThisParameter") && typeArgs.length >= 1) { return this.resolveThisParameterType(typeName, typeArgs[0]); } // Handle Array<T> if (typeName === "Array" && typeArgs.length >= 1) { const elementType = this.resolveTypeNode(typeArgs[0]); return `${elementType}[]`; } // Handle Promise<T> if (typeName === "Promise" && typeArgs.length >= 1) { const valueType = this.resolveTypeNode(typeArgs[0]); return `Promise<${valueType}>`; } // Handle generic types defined across all source files for (const sourceFile of this.sourceFiles) { const baseTypeAlias = sourceFile.getTypeAlias(typeName); if (baseTypeAlias) { return this.resolveGenericTypeAlias(baseTypeAlias, typeArgs); } } // If we can't resolve it, return the original text return typeRef.getText(); } /** * Resolve utility types like Pick and Omit */ resolveUtilityType(utilityName, typeArgs) { const baseTypeArg = typeArgs[0]; const keysArg = typeArgs[1]; // Get the base type const baseType = this.getBaseTypeProperties(baseTypeArg); if (!baseType) { return `{ /* Could not resolve ${utilityName} */ }`; } // Extract the keys const selectedKeys = this.extractKeys(keysArg); // Filter properties based on utility type const resultProperties = []; for (const [propName, propType, isOptional] of baseType) { const shouldInclude = utilityName === "Pick" ? selectedKeys.includes(propName) : !selectedKeys.includes(propName); if (shouldInclude) { const optionalMarker = isOptional ? "?" : ""; resultProperties.push(`${propName}${optionalMarker}: ${propType}`); } } return `{ ${resultProperties.join("; ")} }`; } /** * Resolve Partial or Required utility types */ resolvePartialOrRequired(utilityName, baseTypeArg) { const baseType = this.getBaseTypeProperties(baseTypeArg); if (!baseType) { return `{ /* Could not resolve ${utilityName} */ }`; } const resultProperties = []; for (const [propName, propType, isOptional] of baseType) { let optionalMarker = ""; if (utilityName === "Partial") { optionalMarker = "?"; // Make all properties optional } else if (utilityName === "Required") { optionalMarker = ""; // Make all properties required (remove optional marker) } else { optionalMarker = isOptional ? "?" : ""; // Preserve original optionality } resultProperties.push(`${propName}${optionalMarker}: ${propType}`); } return `{ ${resultProperties.join("; ")} }`; } /** * Get properties from a base type (either a type literal or a type alias reference) */ getBaseTypeProperties(baseTypeArg) { // If it's a type reference, resolve it first if (ts_morph_1.Node.isTypeReference(baseTypeArg)) { const typeName = baseTypeArg.getTypeName().getText(); // Search across all source files for the type alias for (const sourceFile of this.sourceFiles) { const typeAlias = sourceFile.getTypeAlias(typeName); if (typeAlias) { const typeNode = typeAlias.getTypeNode(); if (typeNode) { if (ts_morph_1.Node.isTypeLiteral(typeNode)) { return this.extractPropertiesFromTypeLiteral(typeNode); } // Handle intersection types in type aliases if (ts_morph_1.Node.isIntersectionTypeNode(typeNode)) { return this.getPropertiesFromIntersection(typeNode); } // Handle other type references (recursive resolution) if (ts_morph_1.Node.isTypeReference(typeNode)) { return this.getBaseTypeProperties(typeNode); } } } } // Search across all source files for interfaces for (const sourceFile of this.sourceFiles) { const interfaceDecl = sourceFile.getInterface(typeName); if (interfaceDecl) { return this.extractPropertiesFromInterface(interfaceDecl); } } // Try to resolve through the TypeScript type checker for imported types const properties = this.resolveImportedTypeProperties(baseTypeArg); if (properties) { return properties; } } // If it's a type literal, extract properties directly if (ts_morph_1.Node.isTypeLiteral(baseTypeArg)) { return this.extractPropertiesFromTypeLiteral(baseTypeArg); } // Handle intersection types if (ts_morph_1.Node.isIntersectionTypeNode(baseTypeArg)) { return this.getPropertiesFromIntersection(baseTypeArg); } return null; } /** * Extract properties from an interface declaration */ extractPropertiesFromInterface(interfaceDecl) { const properties = []; for (const member of interfaceDecl.getMembers()) { // Use the same logic as resolveInterfaceDeclaration if (member.getKind() === 167 || member.getName) { // PropertySignature const name = member.getName ? member.getName() : null; const typeNode = member.getTypeNode ? member.getTypeNode() : null; const isOptional = member.hasQuestionToken ? member.hasQuestionToken() : false; if (name && typeNode) { const typeText = this.resolveTypeNode(typeNode); properties.push([name, typeText, isOptional]); } } } return properties; } /** * Extract properties from a type literal */ extractPropertiesFromTypeLiteral(typeLiteral) { if (!ts_morph_1.Node.isTypeLiteral(typeLiteral)) { return []; } const properties = []; for (const member of typeLiteral.getMembers()) { if (ts_morph_1.Node.isPropertySignature(member)) { const name = member.getName(); const typeNode = member.getTypeNode(); const isOptional = member.hasQuestionToken(); if (name && typeNode) { const typeText = this.resolveTypeNode(typeNode); properties.push([name, typeText, isOptional]); } } } return properties; } /** * Extract keys from a union type like 'name' | 'email' */ extractKeys(keysArg) { const keys = []; // Handle union types if (ts_morph_1.Node.isUnionTypeNode(keysArg)) { for (const unionMember of keysArg.getTypeNodes()) { if (ts_morph_1.Node.isLiteralTypeNode(unionMember)) { const literal = unionMember.getLiteral(); if (ts_morph_1.Node.isStringLiteral(literal)) { keys.push(literal.getLiteralValue()); } } } } // Handle single string literal else if (ts_morph_1.Node.isLiteralTypeNode(keysArg)) { const literal = keysArg.getLiteral(); if (ts_morph_1.Node.isStringLiteral(literal)) { keys.push(literal.getLiteralValue()); } } return keys; } /** * Resolve type literals to their string representation */ resolveTypeLiteral(typeLiteral) { if (!ts_morph_1.Node.isTypeLiteral(typeLiteral)) { return typeLiteral.getText(); } const properties = []; for (const member of typeLiteral.getMembers()) { if (ts_morph_1.Node.isPropertySignature(member)) { const name = member.getName(); const typeNode = member.getTypeNode(); const isOptional = member.hasQuestionToken(); if (name && typeNode) { const optionalMarker = isOptional ? "?" : ""; const typeText = this.resolveTypeNode(typeNode); properties.push(`${name}${optionalMarker}: ${typeText}`); } } } return `{ ${properties.join("; ")} }`; } /** * Resolve single-argument utility types like Partial, Required, Readonly, NonNullable */ resolveSingleArgUtilityType(utilityName, baseTypeArg) { if (utilityName === "Partial" || utilityName === "Required") { return this.resolvePartialOrRequired(utilityName, baseTypeArg); } if (utilityName === "Readonly") { return this.resolveReadonlyType(baseTypeArg); } if (utilityName === "NonNullable") { return this.resolveNonNullableType(baseTypeArg); } return `${utilityName}<${this.resolveTypeNode(baseTypeArg)}>`; } /** * Resolve Readonly<T> utility type */ resolveReadonlyType(baseTypeArg) { const baseType = this.getBaseTypeProperties(baseTypeArg); if (!baseType) { return `Readonly<${this.resolveTypeNode(baseTypeArg)}>`; } const resultProperties = []; for (const [propName, propType, isOptional] of baseType) { const optionalMarker = isOptional ? "?" : ""; resultProperties.push(`readonly ${propName}${optionalMarker}: ${propType}`); } return `{ ${resultProperties.join("; ")} }`; } /** * Resolve NonNullable<T> utility type */ resolveNonNullableType(baseTypeArg) { const resolvedType = this.resolveTypeNode(baseTypeArg); // Remove null and undefined from union types if (resolvedType.includes(" | null") || resolvedType.includes(" | undefined")) { return resolvedType .replace(/ \| null/g, "") .replace(/ \| undefined/g, "") .replace(/null \| /g, "") .replace(/undefined \| /g, ""); } return resolvedType; } /** * Resolve Record<K, V> utility type */ resolveRecordType(keysArg, valueArg) { const keys = this.extractKeys(keysArg); const valueType = this.resolveTypeNode(valueArg); if (keys.length > 0) { const properties = keys.map((key) => `${key}: ${valueType}`); return `{ ${properties.join("; ")} }`; } // If we can't extract specific keys, return a generic record type const keyType = this.resolveTypeNode(keysArg); return `{ [key: ${keyType}]: ${valueType} }`; } /** * Resolve Exclude<T, U> and Extract<T, U> utility types */ resolveExcludeExtractType(utilityName, typeArg, excludeArg) { const baseType = this.resolveTypeNode(typeArg); const excludeType = this.resolveTypeNode(excludeArg); // For simple cases, we can try to resolve union types if (baseType.includes(" | ")) { const unionTypes = baseType.split(" | ").map((t) => t.trim()); const excludeTypes = excludeType.includes(" | ") ? excludeType.split(" | ").map((t) => t.trim()) : [excludeType]; let resultTypes; if (utilityName === "Exclude") { resultTypes = unionTypes.filter((t) => !excludeTypes.includes(t)); } else { // Extract resultTypes = unionTypes.filter((t) => excludeTypes.includes(t)); } return resultTypes.length > 1 ? resultTypes.join(" | ") : resultTypes[0] || "never"; } // For complex cases, return the original utility type return `${utilityName}<${baseType}, ${excludeType}>`; } /** * Resolve ReturnType<T> utility type */ resolveReturnType(functionTypeArg) { const functionType = this.resolveTypeNode(functionTypeArg); // Try to extract return type from function signature const arrowMatch = functionType.match(/=>\s*(.+)$/); if (arrowMatch) { return arrowMatch[1].trim(); } // For complex cases, return the utility type return `ReturnType<${functionType}>`; } /** * Resolve Parameters<T> utility type */ resolveParametersType(functionTypeArg) { const functionType = this.resolveTypeNode(functionTypeArg); // Try to extract parameters from function signature const paramsMatch = functionType.match(/\(([^)]*)\)/); if (paramsMatch) { const params = paramsMatch[1].trim(); if (!params) { return "[]"; } // Parse parameters and create tuple type const paramTypes = params.split(",").map((p) => { const colonIndex = p.lastIndexOf(":"); return colonIndex > -1 ? p.substring(colonIndex + 1).trim() : p.trim(); }); return `[${paramTypes.join(", ")}]`; } return `Parameters<${functionType}>`; } /** * Resolve ConstructorParameters<T> utility type */ resolveConstructorParametersType(constructorTypeArg) { const constructorType = this.resolveTypeNode(constructorTypeArg); // Try to extract constructor parameters const constructorMatch = constructorType.match(/new\s*\(([^)]*)\)/); if (constructorMatch) { const params = constructorMatch[1].trim(); if (!params) { return "[]"; } const paramTypes = params.split(",").map((p) => { const colonIndex = p.lastIndexOf(":"); return colonIndex > -1 ? p.substring(colonIndex + 1).trim() : p.trim(); }); return `[${paramTypes.join(", ")}]`; } return `ConstructorParameters<${constructorType}>`; } /** * Resolve InstanceType<T> utility type */ resolveInstanceType(constructorTypeArg) { const constructorType = this.resolveTypeNode(constructorTypeArg); // Try to extract instance type from constructor const instanceMatch = constructorType.match(/new\s*\([^)]*\)\s*:\s*(.+)$/); if (instanceMatch) { return instanceMatch[1].trim(); } return `InstanceType<${constructorType}>`; } /** * Resolve ThisParameterType<T> and OmitThisParameter<T> utility types */ resolveThisParameterType(utilityName, functionTypeArg) { const functionType = this.resolveTypeNode(functionTypeArg); // Try to extract this parameter const thisMatch = functionType.match(/\(this:\s*([^,)]+)/); if (thisMatch) { if (utilityName === "ThisParameterType") { return thisMatch[1].trim(); } else { // OmitThisParameter // Remove this parameter from function signature return functionType.replace(/\(this:\s*[^,)]+,?\s*/, "("); } } if (utilityName === "ThisParameterType") { return "unknown"; } return `${utilityName}<${functionType}>`; } /** * Resolve generic type aliases with type arguments */ resolveGenericTypeAlias(typeAlias, typeArgs) { const typeParams = typeAlias.getTypeParameters(); if (typeParams.length === 0 || typeArgs.length === 0) { return this.resolveTypeAlias(typeAlias); } // Create a mapping of type parameters to type arguments const typeParamMap = new Map(); for (let i = 0; i < Math.min(typeParams.length, typeArgs.length); i++) { const paramName = typeParams[i].getName(); const argType = this.resolveTypeNode(typeArgs[i]); typeParamMap.set(paramName, argType); } // Get the type node and substitute type parameters const typeNode = typeAlias.getTypeNode(); if (!typeNode) { return typeAlias.getName(); } return this.substituteTypeParameters(typeNode, typeParamMap); } /** * Resolve intersection types (A & B) */ resolveIntersectionType(intersectionNode) { if (!ts_morph_1.Node.isIntersectionTypeNode(intersectionNode)) { return intersectionNode.getText(); } const typeNodes = intersectionNode.getTypeNodes(); const resolvedTypes = typeNodes.map((typeNode) => this.resolveTypeNode(typeNode)); // Try to merge object types if possible const objectTypes = []; const nonObjectTypes = []; for (let i = 0; i < typeNodes.length; i++) { const typeNode = typeNodes[i]; const resolvedType = resolvedTypes[i]; // Check if this is an object type we can merge const properties = this.getBaseTypeProperties(typeNode); if (properties) { objectTypes.push(properties); } else { nonObjectTypes.push(resolvedType); } } // If we have object types to merge, merge them if (objectTypes.length > 0) { const mergedProperties = new Map(); // Merge all object properties for (const properties of objectTypes) { for (const [propName, propType, isOptional] of properties) { mergedProperties.set(propName, [propType, isOptional]); } } // Create merged object type const mergedProps = Array.from(mergedProperties.entries()).map(([name, [type, optional]]) => { const optionalMarker = optional ? "?" : ""; return `${name}${optionalMarker}: ${type}`; }); const mergedObject = `{ ${mergedProps.join("; ")} }`; // If there are non-object types, combine them if (nonObjectTypes.length > 0) { return [mergedObject, ...nonObjectTypes].join(" & "); } return mergedObject; } // If no object types to merge, just join with & return resolvedTypes.join(" & "); } /** * Resolve union types (A | B) */ resolveUnionType(unionNode) { if (!ts_morph_1.Node.isUnionTypeNode(unionNode)) { return unionNode.getText(); } const typeNodes = unionNode.getTypeNodes(); const resolvedTypes = typeNodes.map((typeNode) => this.resolveTypeNode(typeNode)); return resolvedTypes.join(" | "); } /** * Get properties from intersection types by merging all constituent types */ getPropertiesFromIntersection(intersectionNode) { if (!ts_morph_1.Node.isIntersectionTypeNode(intersectionNode)) { return null; } const allProperties = new Map(); for (const typeNode of intersectionNode.getTypeNodes()) { const properties = this.getBaseTypeProperties(typeNode); if (properties) { for (const [propName, propType, isOptional] of properties) { allProperties.set(propName, [propType, isOptional]); } } } return Array.from(allProperties.entries()).map(([name, [type, optional]]) => [name, type, optional]); } /** * Try to resolve imported type properties using TypeScript's type checker */ resolveImportedTypeProperties(typeRef) { if (!ts_morph_1.Node.isTypeReference(typeRef)) { return null; } try { // Get the type from the TypeScript type checker const type = typeRef.getType(); const symbol = type.getSymbol(); if (!symbol) { return null; } // Try to get the source declarations const declarations = symbol.getDeclarations(); if (!declarations || declarations.length === 0) { return null; } // Look for interface or type alias declarations for (const declaration of declarations) { if (ts_morph_1.Node.isInterfaceDeclaration(declaration)) { return this.extractPropertiesFromInterface(declaration); } if (ts_morph_1.Node.isTypeAliasDeclaration(declaration)) { const typeNode = declaration.getTypeNode(); if (typeNode && ts_morph_1.Node.isTypeLiteral(typeNode)) { return this.extractPropertiesFromTypeLiteral(typeNode); } } } } catch (error) { // If type checking fails, return null to fall back to other methods return null; } return null; } /** * Substitute type parameters in a type node */ substituteTypeParameters(typeNode, typeParamMap) { // Handle type references if (ts_morph_1.Node.isTypeReference(typeNode)) { const typeName = typeNode.getTypeName().getText(); // If this is a type parameter, substitute it if (typeParamMap.has(typeName)) { return typeParamMap.get(typeName); } // Otherwise, recursively resolve with substitution const typeArgs = typeNode.getTypeArguments(); if (typeArgs.length > 0) { const resolvedArgs = typeArgs.map((arg) => this.substituteTypeParameters(arg, typeParamMap)); return `${typeName}<${resolvedArgs.join(", ")}>`; } return typeName; } // Handle type literals if (ts_morph_1.Node.isTypeLiteral(typeNode)) { const properties = []; for (const member of typeNode.getMembers()) { if (ts_morph_1.Node.isPropertySignature(member)) { const name = member.getName(); const typeNodeMember = member.getTypeNode(); const isOptional = member.hasQuestionToken(); if (name && typeNodeMember) { const optionalMarker = isOptional ? "?" : ""; const typeText = this.substituteTypeParameters(typeNodeMember, typeParamMap); properties.push(`${name}${optionalMarker}: ${typeText}`); } } } return `{ ${properties.join("; ")} }`; } // For other node types, check if it's a simple identifier that needs substitution const text = typeNode.getText(); if (typeParamMap.has(text)) { return typeParamMap.get(text); } return text; } } exports.TypeResolver = TypeResolver; /** * Convenience function to resolve types from source code */ function resolveTypesFromSource(sourceCode, predicate) { const resolver = new TypeResolver(sourceCode); return resolver.resolveTypes(predicate); } /** * Convenience function to get a specific resolved type */ function getResolvedType(sourceCode, typeName) { const resolver = new TypeResolver(sourceCode); return resolver.getResolvedType(typeName); } // Import the factory and related types for enhanced convenience functions const type_resolver_factory_1 = require("./type-resolver-factory"); /** * Enhanced convenience function to resolve types from various input types */ async function resolveTypesFromInput(input, predicate, options) { const resolver = await type_resolver_factory_1.TypeResolverFactory.create(input, options); return resolver.resolveTypes(predicate); } /** * Enhanced convenience function to get a specific resolved type from various input types */ async function getResolvedTypeFromInput(input, typeName, options) { const resolver = await type_resolver_factory_1.TypeResolverFactory.create(input, options); return resolver.getResolvedType(typeName); } /** * Convenience function to resolve types from a directory */ async function resolveTypesFromDirectory(dirPath, options, predicate) { return resolveTypesFromInput(dirPath, predicate, options); } /** * Convenience function to resolve types using glob patterns */ async function resolveTypesFromGlob(dirPath, glob, exclude, predicate, compilerOptions) { return resolveTypesFromInput(dirPath, predicate, { glob, exclude, compilerOptions, }); } /** * Convenience function to resolve types from a single file */ async function resolveTypesFromFile(filePath, predicate, compilerOptions) { return resolveTypesFromInput(filePath, predicate, { compilerOptions }); } /** * Convenience function to get a specific type from a file */ async function getResolvedTypeFromFile(filePath, typeName, compilerOptions) { return getResolvedTypeFromInput(filePath, typeName, { compilerOptions }); } /** * Convenience function to get a specific type from a directory */ async function getResolvedTypeFromDirectory(dirPath, typeName, options) { return getResolvedTypeFromInput(dirPath, typeName, options); } //# sourceMappingURL=type-resolver.js.map