UNPKG

fluent-gen-ts

Version:

Generate type-safe fluent builders for TypeScript interfaces and types

1,565 lines (1,563 loc) 119 kB
import { SourceFile, Symbol, Symbol as Symbol$1, Type, Type as Type$1 } from "ts-morph"; //#region src/core/result.d.ts /** * Represents a successful result containing a value. * @template T - The type of the success value */ type Ok<T> = { readonly ok: true; readonly value: T; }; /** * Represents a failed result containing an error. * @template E - The type of the error value */ type Err<E> = { readonly ok: false; readonly error: E; }; /** * A type representing either success (Ok) or failure (Err). * This is a discriminated union that enables type-safe error handling without exceptions. * * @template T - The type of the success value * @template E - The type of the error value (defaults to Error) * * @example * ```ts * function divide(a: number, b: number): Result<number, string> { * return b === 0 ? err("Division by zero") : ok(a / b); * } * * const result = divide(10, 2); * if (isOk(result)) { * console.log(result.value); // 5 * } else { * console.error(result.error); // Division by zero * } * ``` */ type Result<T, E = Error> = Ok<T> | Err<E>; /** * Creates a successful Result containing the given value. * * @template T - The type of the success value * @param value - The value to wrap in a successful Result * @returns An Ok Result containing the value * * @example * ```ts * const result = ok("Hello, World!"); * console.log(result); // { ok: true, value: "Hello, World!" } * ``` */ declare const ok: <T>(value: T) => Ok<T>; /** * Creates a failed Result containing the given error. * * @template E - The type of the error value * @param error - The error to wrap in a failed Result * @returns An Err Result containing the error * * @example * ```ts * const result = err("Something went wrong"); * console.log(result); // { ok: false, error: "Something went wrong" } * ``` */ declare const err: <E>(error: E) => Err<E>; /** * Type guard function that checks if a Result is Ok. * Narrows the type to Ok<T> when true. * * @template T - The type of the success value * @template E - The type of the error value * @param result - The Result to check * @returns true if the Result is Ok, false otherwise * * @example * ```ts * const result: Result<string, string> = ok("success"); * if (isOk(result)) { * console.log(result.value); // TypeScript knows this is string * } * ``` */ declare const isOk: <T, E>(result: Result<T, E>) => result is Ok<T>; /** * Type guard function that checks if a Result is Err. * Narrows the type to Err<E> when true. * * @template T - The type of the success value * @template E - The type of the error value * @param result - The Result to check * @returns true if the Result is Err, false otherwise * * @example * ```ts * const result: Result<string, string> = err("failure"); * if (isErr(result)) { * console.log(result.error); // TypeScript knows this is string * } * ``` */ declare const isErr: <T, E>(result: Result<T, E>) => result is Err<E>; //#endregion //#region src/core/types.d.ts interface PropertyInfo { readonly name: string; readonly type: TypeInfo; readonly optional: boolean; readonly readonly: boolean; readonly jsDoc?: string; } interface IndexSignature { readonly keyType: 'string' | 'number' | 'symbol'; readonly valueType: TypeInfo; readonly readonly?: boolean; } type TypeInfo = { readonly kind: TypeKind.Primitive; readonly name: string; readonly literal?: unknown; } | { readonly kind: TypeKind.Object; readonly name?: string; readonly properties: readonly PropertyInfo[]; readonly genericParams?: readonly GenericParam[]; readonly indexSignature?: IndexSignature; readonly unresolvedGenerics?: readonly GenericParam[]; readonly typeArguments?: readonly TypeInfo[]; readonly sourceFile?: string; } | { readonly kind: TypeKind.Array; readonly elementType: TypeInfo; } | { readonly kind: TypeKind.Union; readonly unionTypes: readonly TypeInfo[]; } | { readonly kind: TypeKind.Intersection; readonly intersectionTypes: readonly TypeInfo[]; } | { readonly kind: TypeKind.Generic; readonly name: string; readonly typeArguments?: readonly TypeInfo[]; readonly constraint?: TypeInfo; readonly default?: TypeInfo; readonly unresolvedGenerics?: readonly GenericParam[]; } | { readonly kind: TypeKind.Literal; readonly literal: unknown; } | { readonly kind: TypeKind.Unknown; } | { readonly kind: TypeKind.Reference; readonly name: string; readonly typeArguments?: readonly TypeInfo[]; } | { readonly kind: TypeKind.Function; readonly name?: string; } | { readonly kind: TypeKind.Tuple; readonly elements: readonly TypeInfo[]; } | { readonly kind: TypeKind.Enum; readonly name: string; readonly values?: readonly unknown[]; } | { readonly kind: TypeKind.Keyof; readonly target: TypeInfo; } | { readonly kind: TypeKind.Typeof; readonly target: TypeInfo; } | { readonly kind: TypeKind.Index; readonly object: TypeInfo; readonly index: TypeInfo; } | { readonly kind: TypeKind.Conditional; readonly checkType: TypeInfo; readonly extendsType: TypeInfo; readonly trueType: TypeInfo; readonly falseType: TypeInfo; readonly inferredTypes?: Record<string, TypeInfo>; } | { readonly kind: TypeKind.Never; }; interface GenericParam { readonly name: string; readonly constraint?: TypeInfo; readonly default?: TypeInfo; } declare enum TypeKind { Primitive = "primitive", Object = "object", Array = "array", Union = "union", Intersection = "intersection", Generic = "generic", Literal = "literal", Unknown = "unknown", Reference = "reference", Function = "function", Tuple = "tuple", Enum = "enum", Keyof = "keyof", Typeof = "typeof", Index = "index", Conditional = "conditional", Never = "never", } interface ResolvedType { readonly sourceFile: string; readonly name: string; readonly typeInfo: TypeInfo; readonly imports: readonly string[]; readonly dependencies: readonly ResolvedType[]; } interface GeneratorOptions { outputPath?: string; useDefaults?: boolean; contextType?: string; importPath?: string; } //#endregion //#region src/core/plugin/type-matcher/matcher-base.d.ts /** * Base type matcher interface */ interface TypeMatcher$1 { match(typeInfo: TypeInfo): boolean; describe(): string; } /** * Base implementation for type matchers */ declare abstract class BaseTypeMatcher implements TypeMatcher$1 { abstract match(typeInfo: TypeInfo): boolean; abstract describe(): string; } //#endregion //#region src/core/plugin/type-matcher/matchers/object-matcher.d.ts /** * Object type matcher with fluent API */ interface ObjectTypeMatcher$1 extends TypeMatcher$1 { withGeneric(name?: string): ObjectTypeMatcher$1; withProperty(name: string, type?: TypeMatcher$1): ObjectTypeMatcher$1; withProperties(...names: string[]): ObjectTypeMatcher$1; } /** * Matcher for object types */ declare class ObjectMatcher extends BaseTypeMatcher implements ObjectTypeMatcher$1 { private name?; private genericName?; private requiredProperties; constructor(name?: string); /** * Adds a generic parameter constraint to this object matcher. * * @param name - Optional generic parameter name. If provided, matches objects with this specific generic. * If empty string, matches objects with any generic. If undefined, no generic constraint. * @returns This ObjectTypeMatcher for method chaining * * @example * ```typescript * object('Array').withGeneric('T') // Matches Array<T> * object('Map').withGeneric() // Matches Map with any generics * ``` */ withGeneric(name?: string): ObjectTypeMatcher$1; /** * Adds a required property constraint to this object matcher. * * @param name - The property name that must exist on the object * @param type - Optional type matcher for the property's type * @returns This ObjectTypeMatcher for method chaining * * @example * ```typescript * object('User').withProperty('id', primitive('string')) * object().withProperty('name') // Any object with a 'name' property * ``` */ withProperty(name: string, type?: TypeMatcher$1): ObjectTypeMatcher$1; /** * Adds multiple required property constraints to this object matcher. * * @param names - Property names that must exist on the object * @returns This ObjectTypeMatcher for method chaining * * @example * ```typescript * object('User').withProperties('id', 'name', 'email') * ``` */ withProperties(...names: string[]): ObjectTypeMatcher$1; match(typeInfo: TypeInfo): boolean; describe(): string; } /** * Creates a matcher for object types with optional name and property constraints. * * @param name - Optional object type name to match * @returns An ObjectTypeMatcher for further configuration * * @example * ```typescript * object('User').withProperty('id', primitive('string')) * object().withProperties('name', 'email') // Any object with these properties * ``` */ declare const object: (name?: string) => ObjectMatcher; //#endregion //#region src/core/plugin/type-matcher/matchers/array-matcher.d.ts /** * Array type matcher with fluent API */ interface ArrayTypeMatcher$1 extends TypeMatcher$1 { of(matcher: TypeMatcher$1): ArrayTypeMatcher$1; } /** * Matcher for array types */ declare class ArrayMatcher extends BaseTypeMatcher implements ArrayTypeMatcher$1 { private elementMatcher?; /** * Adds an element type constraint to this array matcher. * * @param matcher - Type matcher for array elements * @returns This ArrayTypeMatcher for method chaining * * @example * ```typescript * array().of(primitive('string')) // Array of strings * array().of(object('User')) // Array of User objects * ``` */ of(matcher: TypeMatcher$1): ArrayTypeMatcher$1; match(typeInfo: TypeInfo): boolean; describe(): string; } /** * Creates a matcher for array types with optional element type constraints. * * @returns An ArrayTypeMatcher for further configuration * * @example * ```typescript * array().of(primitive('string')) // Array of strings * array() // Any array type * ``` */ declare const array: () => ArrayMatcher; //#endregion //#region src/core/plugin/type-matcher/matchers/union-matcher.d.ts /** * Union type matcher with fluent API */ interface UnionTypeMatcher$1 extends TypeMatcher$1 { containing(matcher: TypeMatcher$1): UnionTypeMatcher$1; exact(...matchers: TypeMatcher$1[]): UnionTypeMatcher$1; } /** * Matcher for union types */ declare class UnionMatcher extends BaseTypeMatcher implements UnionTypeMatcher$1 { private containingMatchers; private exactMatchers; /** * Adds a containment constraint - the union must contain a type matching this matcher. * * @param matcher - Type matcher that must be contained in the union * @returns This UnionTypeMatcher for method chaining * * @example * ```typescript * union().containing(primitive('string')) // Union that contains string * union().containing(primitive('string')).containing(primitive('number')) // Union containing both string and number * ``` */ containing(matcher: TypeMatcher$1): UnionTypeMatcher$1; /** * Sets exact matching constraints - the union must match exactly these matchers (no more, no less). * * @param matchers - Array of type matchers that must exactly match the union types * @returns This UnionTypeMatcher for method chaining * * @example * ```typescript * union().exact(primitive('string'), primitive('number')) // Union of exactly string | number * union().exact(primitive('string'), literal('null')) // Union of exactly string | null * ``` */ exact(...matchers: TypeMatcher$1[]): UnionTypeMatcher$1; match(typeInfo: TypeInfo): boolean; describe(): string; } /** * Creates a matcher for union types with containment or exact matching constraints. * * @returns A UnionTypeMatcher for further configuration * * @example * ```typescript * union().containing(primitive('string')).containing(primitive('number')) * union().exact(primitive('string'), primitive('null')) * ``` */ declare const union: () => UnionMatcher; //#endregion //#region src/core/plugin/type-matcher/matchers/intersection-matcher.d.ts /** * Intersection type matcher with fluent API */ interface IntersectionTypeMatcher$1 extends TypeMatcher$1 { including(matcher: TypeMatcher$1): IntersectionTypeMatcher$1; exact(...matchers: TypeMatcher$1[]): IntersectionTypeMatcher$1; } /** * Matcher for intersection types */ declare class IntersectionMatcher extends BaseTypeMatcher implements IntersectionTypeMatcher$1 { private includingMatchers; private exactMatchers; /** * Adds an inclusion constraint - the intersection must include a type matching this matcher. * * @param matcher - Type matcher that must be included in the intersection * @returns This IntersectionTypeMatcher for method chaining * * @example * ```typescript * intersection().including(object('Base')) // Intersection that includes Base * intersection().including(object('Base')).including(object('Mixin')) // Intersection including both Base and Mixin * ``` */ including(matcher: TypeMatcher$1): IntersectionTypeMatcher$1; /** * Sets exact matching constraints - the intersection must match exactly these matchers (no more, no less). * * @param matchers - Array of type matchers that must exactly match the intersection types * @returns This IntersectionTypeMatcher for method chaining * * @example * ```typescript * intersection().exact(object('A'), object('B')) // Intersection of exactly A & B * intersection().exact(object('Base'), object('Mixin')) // Intersection of exactly Base & Mixin * ``` */ exact(...matchers: TypeMatcher$1[]): IntersectionTypeMatcher$1; match(typeInfo: TypeInfo): boolean; describe(): string; } /** * Creates a matcher for intersection types with inclusion or exact matching constraints. * * @returns An IntersectionTypeMatcher for further configuration * * @example * ```typescript * intersection().including(object('Base')).including(object('Mixin')) * intersection().exact(object('A'), object('B')) * ``` */ declare const intersection: () => IntersectionMatcher; //#endregion //#region src/core/plugin/type-matcher/matcher-builder.d.ts /** * Type matcher builder interface */ interface TypeMatcherBuilder$1 { primitive(...names: string[]): TypeMatcher$1; object(name?: string): ObjectTypeMatcher$1; array(): ArrayTypeMatcher$1; union(): UnionTypeMatcher$1; intersection(): IntersectionTypeMatcher$1; reference(name?: string): TypeMatcher$1; generic(name?: string): TypeMatcher$1; any(): TypeMatcher$1; never(): TypeMatcher$1; literal(value: string | number | boolean): TypeMatcher$1; or(...matchers: TypeMatcher$1[]): TypeMatcher$1; and(...matchers: TypeMatcher$1[]): TypeMatcher$1; not(matcher: TypeMatcher$1): TypeMatcher$1; } /** * Creates a new type matcher builder for composing complex matchers * * @returns A TypeMatcherBuilder instance * * @example * ```typescript * const m = createTypeMatcher(); * const matcher = m.union() * .containing(m.primitive('string')) * .containing(m.object('User')); * ``` */ declare function createTypeMatcher(): TypeMatcherBuilder$1; //#endregion //#region src/core/plugin/type-matcher/matchers/primitive-matcher.d.ts /** * Matcher for primitive types */ declare class PrimitiveMatcher extends BaseTypeMatcher { private readonly names; constructor(names: string[]); match(typeInfo: TypeInfo): boolean; describe(): string; } /** * Creates a matcher for primitive types (string, number, boolean, etc.). * * @param names - Optional specific primitive type names to match. If empty, matches any primitive. * @returns A TypeMatcher for primitive types * * @example * ```typescript * primitive('string', 'number') // Matches string or number * primitive() // Matches any primitive type * ``` */ declare const primitive: (...names: string[]) => PrimitiveMatcher; //#endregion //#region src/core/plugin/type-matcher/matchers/reference-matcher.d.ts /** * Matcher for reference types */ declare class ReferenceMatcher extends BaseTypeMatcher { private readonly name?; constructor(name?: string | undefined); match(typeInfo: TypeInfo): boolean; describe(): string; } /** * Creates a matcher for reference types (type aliases, imported types). * * @param name - Optional reference type name to match * @returns A TypeMatcher for reference types * * @example * ```typescript * reference('MyType') // Matches references to MyType * reference() // Matches any reference type * ``` */ declare const reference: (name?: string) => ReferenceMatcher; //#endregion //#region src/core/plugin/type-matcher/matchers/generic-matcher.d.ts /** * Matcher for generic types */ declare class GenericMatcher extends BaseTypeMatcher { private readonly name?; constructor(name?: string | undefined); match(typeInfo: TypeInfo): boolean; describe(): string; } /** * Creates a matcher for generic type parameters. * * @param name - Optional generic parameter name to match * @returns A TypeMatcher for generic types * * @example * ```typescript * generic('T') // Matches generic parameter T * generic() // Matches any generic parameter * ``` */ declare const generic: (name?: string) => GenericMatcher; //#endregion //#region src/core/plugin/type-matcher/matchers/literal-matcher.d.ts /** * Matcher for literal types */ declare class LiteralMatcher extends BaseTypeMatcher { private readonly value; constructor(value: string | number | boolean); match(typeInfo: TypeInfo): boolean; describe(): string; } /** * Creates a matcher for literal types with specific values. * * @param value - The literal value to match (string, number, or boolean) * @returns A TypeMatcher for the specific literal value * * @example * ```typescript * literal('success') // Matches the literal string 'success' * literal(42) // Matches the literal number 42 * literal(true) // Matches the literal boolean true * ``` */ declare const literal: (value: string | number | boolean) => LiteralMatcher; //#endregion //#region src/core/plugin/type-matcher/matchers/special-matchers.d.ts /** * Matcher that matches any type */ declare class AnyMatcher extends BaseTypeMatcher { match(_typeInfo: TypeInfo): boolean; describe(): string; } /** * Matcher for never type */ declare class NeverMatcher extends BaseTypeMatcher { match(typeInfo: TypeInfo): boolean; describe(): string; } /** * Creates a matcher that matches any type. * * @returns A TypeMatcher that always matches * * @example * ```typescript * any() // Matches any type including primitives, objects, arrays, etc. * ``` */ declare const any: () => AnyMatcher; /** * Creates a matcher for the never type. * * @returns A TypeMatcher for the never type * * @example * ```typescript * never() // Matches the never type * ``` */ declare const never: () => NeverMatcher; //#endregion //#region src/core/plugin/type-matcher/matchers/logical-matchers.d.ts /** * Logical OR matcher */ declare class OrMatcher extends BaseTypeMatcher { private readonly matchers; constructor(matchers: TypeMatcher$1[]); match(typeInfo: TypeInfo): boolean; describe(): string; } /** * Logical AND matcher */ declare class AndMatcher extends BaseTypeMatcher { private readonly matchers; constructor(matchers: TypeMatcher$1[]); match(typeInfo: TypeInfo): boolean; describe(): string; } /** * Logical NOT matcher */ declare class NotMatcher extends BaseTypeMatcher { private readonly matcher; constructor(matcher: TypeMatcher$1); match(typeInfo: TypeInfo): boolean; describe(): string; } /** * Creates a logical OR matcher that matches if any of the provided matchers match. * * @param matchers - Array of matchers to combine with OR logic * @returns A TypeMatcher using OR logic * * @example * ```typescript * or(primitive('string'), primitive('number')) // Matches string OR number * or(object('User'), object('Admin')) // Matches User OR Admin objects * ``` */ declare const or: (...matchers: TypeMatcher$1[]) => OrMatcher; /** * Creates a logical AND matcher that matches only if all provided matchers match. * * @param matchers - Array of matchers to combine with AND logic * @returns A TypeMatcher using AND logic * * @example * ```typescript * and(object(), not(primitive())) // Matches objects that are not primitives * ``` */ declare const and: (...matchers: TypeMatcher$1[]) => AndMatcher; /** * Creates a logical NOT matcher that matches when the provided matcher does not match. * * @param matcher - The matcher to negate * @returns A TypeMatcher using NOT logic * * @example * ```typescript * not(primitive('string')) // Matches any type except string * not(object('User')) // Matches any type except User objects * ``` */ declare const not: (matcher: TypeMatcher$1) => NotMatcher; //#endregion //#region src/core/plugin/type-matcher/transformation/type-to-string.d.ts /** * Converts a TypeInfo object to its string representation * * @param typeInfo - The TypeInfo to convert * @returns String representation of the type * * @example * ```typescript * const typeInfo: TypeInfo = { kind: TypeKind.Primitive, name: 'string' }; * typeInfoToString(typeInfo) // Returns 'string' * * const arrayType: TypeInfo = { * kind: TypeKind.Array, * elementType: { kind: TypeKind.Primitive, name: 'number' } * }; * typeInfoToString(arrayType) // Returns 'Array<number>' * ``` */ declare function typeInfoToString(typeInfo: TypeInfo): string; //#endregion //#region src/core/plugin/type-matcher/transformation/transform-deep.d.ts /** * Options for transformTypeDeep function */ interface TransformTypeDeepOptions { /** Whether to include FluentBuilder unions for named object types */ readonly includeBuilderTypes?: boolean; /** Name of the FluentBuilder type (default: 'FluentBuilder') */ readonly builderTypeName?: string; /** Name of the context type (default: 'BaseBuildContext') */ readonly contextTypeName?: string; } /** * Transformer interface for deep type transformations * * Each handler receives a type of specific kind and can return: * - A string to use as the transformed type * - A TypeInfo to continue transforming recursively * - null/undefined to skip transformation (preserve original) * * @example * ```typescript * import { primitive } from './matchers/primitive-matcher.js'; * * const transformer: TypeTransformer = { * onPrimitive: (type) => { * if (primitive('string').match(type)) { * return 'string | { value: string }'; * } * return null; // preserve other primitives * } * }; * ``` */ interface TypeTransformer$1 { /** Transform primitive types */ onPrimitive?: (type: TypeInfo & { kind: TypeKind.Primitive; }) => string | TypeInfo | null; /** Transform object types (before processing properties) */ onObject?: (type: TypeInfo & { kind: TypeKind.Object; }) => string | TypeInfo | null; /** Transform array types (before processing element) */ onArray?: (type: TypeInfo & { kind: TypeKind.Array; }) => string | TypeInfo | null; /** Transform union types (before processing members) */ onUnion?: (type: TypeInfo & { kind: TypeKind.Union; }) => string | TypeInfo | null; /** Transform intersection types (before processing members) */ onIntersection?: (type: TypeInfo & { kind: TypeKind.Intersection; }) => string | TypeInfo | null; /** Transform generic types */ onGeneric?: (type: TypeInfo & { kind: TypeKind.Generic; }) => string | TypeInfo | null; /** Transform literal types */ onLiteral?: (type: TypeInfo & { kind: TypeKind.Literal; }) => string | TypeInfo | null; /** Transform reference types */ onReference?: (type: TypeInfo & { kind: TypeKind.Reference; }) => string | TypeInfo | null; /** Transform tuple types */ onTuple?: (type: TypeInfo & { kind: TypeKind.Tuple; }) => string | TypeInfo | null; /** Transform any type (fallback) */ onAny?: (type: TypeInfo) => string | TypeInfo | null; } declare function transformTypeDeep(typeInfo: TypeInfo, transformer: TypeTransformer$1, options?: TransformTypeDeepOptions): string; //#endregion //#region src/core/plugin/type-matcher/transformation/deep-matching.d.ts /** * Checks if a type contains a matching type at any depth in its structure * * Recursively searches through: * - Array element types * - Object property types * - Union/Intersection members * - Tuple elements * * @param typeInfo - The type to search within * @param matcher - The type matcher to use for matching * @returns true if any nested type matches * * @example * ```typescript * const complexType: TypeInfo = { * kind: TypeKind.Object, * properties: [{ * name: 'data', * type: { * kind: TypeKind.Array, * elementType: { kind: TypeKind.Primitive, name: 'string' } * } * }] * }; * * containsTypeDeep(complexType, primitive('string')) // Returns true * containsTypeDeep(complexType, primitive('number')) // Returns false * ``` */ declare function containsTypeDeep(typeInfo: TypeInfo, matcher: TypeMatcher$1): boolean; /** * Finds all types matching the given matcher at any depth in the type structure * * @param typeInfo - The type to search within * @param matcher - The type matcher to use for matching * @returns Array of all matching TypeInfo objects found at any depth * * @example * ```typescript * const complexType: TypeInfo = { * kind: TypeKind.Union, * unionTypes: [ * { kind: TypeKind.Primitive, name: 'string' }, * { * kind: TypeKind.Array, * elementType: { kind: TypeKind.Primitive, name: 'string' } * } * ] * }; * * const strings = findTypesDeep(complexType, primitive('string')); * // Returns [{ kind: 'primitive', name: 'string' }, { kind: 'primitive', name: 'string' }] * ``` */ declare function findTypesDeep(typeInfo: TypeInfo, matcher: TypeMatcher$1): TypeInfo[]; //#endregion //#region src/core/plugin/type-matcher/transformation/deep-transformer.d.ts /** * Context information for type transformation predicates */ interface TypeTransformContext$1 { /** Current type being examined */ readonly type: TypeInfo; /** Depth in the type tree (0 = root) */ readonly depth: number; /** Path from root to current type (property names or array indices) */ readonly path: readonly string[]; } /** * Fluent API for deep type transformations with chained replacements * * @example * ```typescript * const transformer = new TypeDeepTransformer(propertyType) * .replace(primitive('string'), 'string | { value: string }') * .replace(primitive('number'), 'number | { value: number }') * .withBuilderTypes() // Enable FluentBuilder unions * .toString(); * ``` */ declare class TypeDeepTransformer { private readonly typeInfo; private replacements; private options; constructor(typeInfo: TypeInfo); /** * Replace all occurrences of types matching the given matcher * * @param matcher - Type matcher to identify types to replace * @param replacement - Replacement string or function * @returns This transformer for chaining * * @example * ```typescript * transformer.replace(primitive('string'), 'string | { value: string }') * transformer.replace(object('User'), type => `Enhanced${type.name}`) * ``` */ replace(matcher: TypeMatcher$1, replacement: string | ((type: TypeInfo) => string)): TypeDeepTransformer; /** * Replace types matching a custom predicate * * @param predicate - Function to determine if type should be replaced * @param replacement - Replacement string or function * @returns This transformer for chaining * * @example * ```typescript * transformer.replaceIf( * (type, depth) => depth > 2 && type.kind === TypeKind.Primitive, * 'unknown' * ) * ``` */ replaceIf(predicate: (type: TypeInfo, depth: number, path: readonly string[]) => boolean, replacement: string | ((type: TypeInfo) => string)): TypeDeepTransformer; /** * Configure builder type generation options * * @param options - Options for builder type generation * @returns This transformer for chaining */ withOptions(options: TransformTypeDeepOptions): TypeDeepTransformer; /** * Execute transformations and return the resulting type string * * @returns Transformed type as a string */ toString(): string; /** * Check if the type contains a match for the given matcher at any depth * * @param matcher - Type matcher to search for * @returns true if any nested type matches */ hasMatch(matcher: TypeMatcher$1): boolean; /** * Find all types matching the given matcher at any depth * * @param matcher - Type matcher to search for * @returns Array of all matching types */ findMatches(matcher: TypeMatcher$1): TypeInfo[]; } //#endregion //#region src/core/plugin/plugin-types.d.ts /** * Generic type for values that can be static or dynamically generated from context * * @example * ```typescript * // Static value * const staticCode: StaticOrDynamic<string, BuilderContext> = "return {};"; * * // Dynamic value based on context * const dynamicCode: StaticOrDynamic<string, BuilderContext> = * (context) => `return new ${context.builderName}();`; * ``` */ type StaticOrDynamic<TValue, TContext> = TValue | ((context: TContext) => TValue); /** * Base import properties shared by all import types * @internal */ interface BaseImportProperties { readonly imports: readonly string[]; readonly isTypeOnly?: boolean; readonly isDefault?: boolean; readonly defaultName?: string; } /** * Represents an internal project import */ interface InternalImport extends BaseImportProperties { readonly kind: 'internal'; readonly path: string; } /** * Represents an external package import */ interface ExternalImport extends BaseImportProperties { readonly kind: 'external'; readonly package: string; } /** * Union type for all import types */ type Import = InternalImport | ExternalImport; /** * Import requirements for a plugin */ interface PluginImports { readonly imports: readonly Import[]; } /** * Base context with common properties */ interface BaseContext { readonly typeName: string; readonly typeInfo: TypeInfo; } /** * Context with builder information */ interface BuilderContextInfo extends BaseContext { readonly builderName: string; } /** * Context with generic parameters */ interface GenericsContextInfo { readonly genericParams: string; readonly genericConstraints: string; } /** * Parse context */ interface ParseContext { readonly sourceFile: string; readonly typeName: string; } /** * Resolve context */ interface ResolveContext { readonly type: Type$1; readonly symbol?: Symbol$1; readonly sourceFile?: string; readonly typeName?: string; } /** * Generate context */ interface GenerateContext { readonly resolvedType: ResolvedType; readonly options: GeneratorOptions; } /** * Build method context */ interface BuildMethodContext extends BuilderContextInfo, GenericsContextInfo { readonly buildMethodCode: string; readonly properties: readonly PropertyInfo[]; readonly options: GeneratorOptions; readonly resolvedType: ResolvedType; } /** * Type matcher for fluent type checking and analysis * * Provides a fluent API for checking and analyzing TypeScript types in plugin contexts. * This interface allows plugins to make decisions based on type characteristics. * * @example * ```typescript * // Check if type is a specific primitive * if (context.type.isPrimitive('string', 'number')) { * // Handle string or number types * } * * // Check complex object types * if (context.type.isObject('User').withProperty('id', m => m.primitive('string'))) { * // Handle User objects with string id property * } * ``` */ interface TypeMatcherInterface { /** Check if type is one of the specified primitive types */ isPrimitive(...names: string[]): boolean; /** Get an object type matcher for fluent checking */ isObject(name?: string): ObjectTypeMatcher; /** Get an array type matcher for fluent checking */ isArray(): ArrayTypeMatcher; /** Get a union type matcher for fluent checking */ isUnion(): UnionTypeMatcher; /** Get an intersection type matcher for fluent checking */ isIntersection(): IntersectionTypeMatcher; /** Check if type is a reference to a named type */ isReference(name?: string): boolean; /** Check if type is or contains generics */ isGeneric(name?: string): boolean; /** Check if type matches a custom type matcher */ matches(matcher: TypeMatcher): boolean; /** Get string representation of the type */ toString(): string; /** Get a deep type transformer for recursive type transformations */ transformDeep(): TypeDeepTransformer; /** Check if type contains a matching type at any depth */ containsDeep(matcher: TypeMatcher): boolean; /** Find all types matching the given matcher at any depth */ findDeep(matcher: TypeMatcher): TypeInfo[]; } /** * Property method context with type utilities */ interface PropertyMethodContext extends BuilderContextInfo { readonly property: PropertyInfo; readonly propertyType: TypeInfo; readonly originalTypeString: string; readonly type: TypeMatcherInterface; hasGeneric(name: string): boolean; getGenericConstraint(name: string): string | undefined; isOptional(): boolean; isReadonly(): boolean; getPropertyPath(): string[]; getMethodName(): string; } /** * Builder context for custom methods */ interface BuilderContext extends BuilderContextInfo, GenericsContextInfo { readonly properties: readonly PropertyInfo[]; hasProperty(name: string): boolean; getProperty(name: string): PropertyInfo | undefined; getRequiredProperties(): readonly PropertyInfo[]; getOptionalProperties(): readonly PropertyInfo[]; } /** * Value context */ interface ValueContext { readonly property: string; readonly valueVariable: string; readonly type: TypeInfo; readonly isOptional: boolean; readonly typeChecker: TypeMatcherInterface; } /** * Property method transformation result */ interface PropertyMethodTransform { readonly parameterType?: string | ((context: PropertyMethodContext) => string); readonly extractValue?: string; readonly validate?: string; } /** * Custom method definition */ interface CustomMethod { readonly name: string; readonly signature: string; readonly implementation: string; readonly jsDoc?: string; } /** * Value transformation result */ interface ValueTransform { readonly condition?: string; readonly transform: string; } /** * Represents a structured import statement with parsed components */ interface StructuredImport { /** The module path or package name */ readonly source: string; /** Named imports (e.g., { Foo, Bar }) */ readonly namedImports: readonly StructuredNamedImport[]; /** Default import name (e.g., React in 'import React from "react"') */ readonly defaultImport?: string; /** Namespace import name (e.g., utils in 'import * as utils from "./utils"') */ readonly namespaceImport?: string; /** Whether this is a type-only import */ readonly isTypeOnly: boolean; /** Whether this is a side-effect import (e.g., 'import "./styles.css"') */ readonly isSideEffect: boolean; } /** * Represents a named import with optional type-only flag */ interface StructuredNamedImport { /** The imported name */ readonly name: string; /** The alias if using 'as' syntax */ readonly alias?: string; /** Whether this specific import is type-only */ readonly isTypeOnly?: boolean; } /** * Enhanced import transformation context with structured imports */ interface ImportTransformContext { /** Structured import objects for easy manipulation */ readonly imports: readonly StructuredImport[]; /** The resolved type being generated */ readonly resolvedType: ResolvedType; /** Whether generating multiple builders */ readonly isGeneratingMultiple: boolean; /** Whether common imports file exists */ readonly hasExistingCommon: boolean; /** Helper utilities for common transformations */ readonly utils: ImportTransformUtils; } /** * Utility functions for import transformations */ interface ImportTransformUtils { /** Transform relative imports to monorepo package imports */ transformRelativeToMonorepo(imports: readonly StructuredImport[], mapping: RelativeToMonorepoMapping): readonly StructuredImport[]; /** Create a new structured import */ createImport(source: string, options?: CreateImportOptions): StructuredImport; /** Merge imports from the same source */ mergeImports(imports: readonly StructuredImport[]): readonly StructuredImport[]; /** Filter imports by source pattern */ filterImports(imports: readonly StructuredImport[], predicate: (imp: StructuredImport) => boolean): readonly StructuredImport[]; /** Replace import sources using pattern matching */ replaceSource(imports: readonly StructuredImport[], options: { from: string | RegExp; to: string; }): readonly StructuredImport[]; } /** * Options for creating structured imports */ interface CreateImportOptions { /** Named imports to include */ namedImports?: readonly (string | StructuredNamedImport)[]; /** Default import name */ defaultImport?: string; /** Namespace import name */ namespaceImport?: string; /** Whether this is a type-only import */ isTypeOnly?: boolean; /** Whether this is a side-effect import */ isSideEffect?: boolean; } /** * Pattern matching rule for relative import transformation */ interface PathMappingRule { /** The pattern to match - can be exact string or regex pattern */ readonly pattern: string; /** Whether the pattern should be treated as a regular expression */ readonly isRegex?: boolean; /** The replacement package name */ readonly replacement: string; } /** * Configuration for transforming relative imports to monorepo imports */ interface RelativeToMonorepoMapping { /** Array of path mapping rules */ readonly pathMappings: readonly PathMappingRule[]; /** Base directory for resolving relative paths */ readonly baseDir?: string; } declare const HookType: { readonly BeforeParse: "beforeParse"; readonly AfterParse: "afterParse"; readonly BeforeResolve: "beforeResolve"; readonly AfterResolve: "afterResolve"; readonly BeforeGenerate: "beforeGenerate"; readonly AfterGenerate: "afterGenerate"; readonly TransformType: "transformType"; readonly TransformProperty: "transformProperty"; readonly TransformBuildMethod: "transformBuildMethod"; readonly TransformPropertyMethod: "transformPropertyMethod"; readonly AddCustomMethods: "addCustomMethods"; readonly TransformValue: "transformValue"; readonly TransformImports: "transformImports"; }; type HookTypeValue = (typeof HookType)[keyof typeof HookType]; /** * Plugin hook map */ interface PluginHookMap { [HookType.BeforeParse]: (context: ParseContext) => Result<ParseContext>; [HookType.AfterParse]: (context: ParseContext, type: Type$1) => Result<Type$1>; [HookType.BeforeResolve]: (context: ResolveContext) => Result<ResolveContext>; [HookType.AfterResolve]: (context: ResolveContext, typeInfo: TypeInfo) => Result<TypeInfo>; [HookType.BeforeGenerate]: (context: GenerateContext) => Result<GenerateContext>; [HookType.AfterGenerate]: (code: string, context: GenerateContext) => Result<string>; [HookType.TransformType]: (type: Type$1, typeInfo: TypeInfo) => Result<TypeInfo>; [HookType.TransformProperty]: (property: PropertyInfo) => Result<PropertyInfo>; [HookType.TransformBuildMethod]: (context: BuildMethodContext) => Result<string>; [HookType.TransformPropertyMethod]: (context: PropertyMethodContext) => Result<PropertyMethodTransform>; [HookType.AddCustomMethods]: (context: BuilderContext) => Result<readonly CustomMethod[]>; [HookType.TransformValue]: (context: ValueContext) => Result<ValueTransform | null>; [HookType.TransformImports]: (context: ImportTransformContext) => Result<ImportTransformContext>; } /** * Base type matcher interface */ interface TypeMatcher { match(typeInfo: TypeInfo): boolean; describe(): string; } /** * Object type matcher with fluent API */ interface ObjectTypeMatcher extends TypeMatcher { withGeneric(name?: string): ObjectTypeMatcher; withProperty(name: string, type?: TypeMatcher): ObjectTypeMatcher; withProperties(...names: string[]): ObjectTypeMatcher; } /** * Array type matcher with fluent API */ interface ArrayTypeMatcher extends TypeMatcher { of(matcher: TypeMatcher | ((m: TypeMatcherBuilder) => TypeMatcher)): ArrayTypeMatcher; } /** * Union type matcher with fluent API */ interface UnionTypeMatcher extends TypeMatcher { containing(matcher: TypeMatcher | ((m: TypeMatcherBuilder) => TypeMatcher)): UnionTypeMatcher; exact(...matchers: TypeMatcher[]): UnionTypeMatcher; } /** * Intersection type matcher with fluent API */ interface IntersectionTypeMatcher extends TypeMatcher { including(matcher: TypeMatcher | ((m: TypeMatcherBuilder) => TypeMatcher)): IntersectionTypeMatcher; exact(...matchers: TypeMatcher[]): IntersectionTypeMatcher; } /** * Type matcher builder for creating complex matchers */ interface TypeMatcherBuilder { primitive(...names: string[]): TypeMatcher; object(name?: string): ObjectTypeMatcher; array(): ArrayTypeMatcher; union(): UnionTypeMatcher; intersection(): IntersectionTypeMatcher; reference(name?: string): TypeMatcher; generic(name?: string): TypeMatcher; any(): TypeMatcher; never(): TypeMatcher; literal(value: string | number | boolean): TypeMatcher; or(...matchers: TypeMatcher[]): TypeMatcher; and(...matchers: TypeMatcher[]): TypeMatcher; not(matcher: TypeMatcher): TypeMatcher; } /** * Plugin interface for extending code generation behavior * * Plugins provide hooks into various stages of the generation pipeline, * allowing customization of parsing, type resolution, and code generation. * * @example * ```typescript * const myPlugin: Plugin = { * name: 'my-custom-plugin', * version: '1.0.0', * description: 'Adds custom validation methods', * * // Transform property methods to add validation * transformPropertyMethod: (context) => { * if (context.type.isPrimitive('string')) { * return ok({ * parameterType: 'string | ValidatedString', * validate: 'validateString(value)' * }); * } * return ok({}); * } * }; * ``` */ interface Plugin { /** Unique identifier for the plugin */ readonly name: string; /** Semantic version of the plugin */ readonly version: string; /** Human-readable description of plugin functionality */ readonly description?: string; /** Import requirements for generated code */ readonly imports?: PluginImports; /** * Custom context type name to use in generated builders (e.g., 'MyDomainContext') * This is used during code generation to specify the context type in builder signatures. * * Note: Runtime context generator behavior should be provided by users via * `__nestedContextGenerator__` in their context objects, not through plugins. */ readonly contextTypeName?: string; beforeParse?: PluginHookMap['beforeParse']; afterParse?: PluginHookMap['afterParse']; beforeResolve?: PluginHookMap['beforeResolve']; afterResolve?: PluginHookMap['afterResolve']; beforeGenerate?: PluginHookMap['beforeGenerate']; afterGenerate?: PluginHookMap['afterGenerate']; transformType?: PluginHookMap['transformType']; transformProperty?: PluginHookMap['transformProperty']; transformBuildMethod?: PluginHookMap['transformBuildMethod']; transformPropertyMethod?: PluginHookMap['transformPropertyMethod']; addCustomMethods?: PluginHookMap['addCustomMethods']; transformValue?: PluginHookMap['transformValue']; transformImports?: PluginHookMap['transformImports']; } /** * Property method transform rule */ interface PropertyMethodTransformRule { readonly predicate: (context: PropertyMethodContext) => boolean; readonly transform: PropertyMethodTransform & { parameterType?: string | ((context: PropertyMethodContext) => string); }; } /** * Value transform rule */ interface ValueTransformRule { readonly predicate: (context: ValueContext) => boolean; readonly transform: ValueTransform; } /** * Build method transformation */ interface BuildMethodTransformation { readonly type: 'insertBefore' | 'insertAfter' | 'replace' | 'wrap'; readonly marker?: string | RegExp; readonly code: StaticOrDynamic<string, BuildMethodContext>; readonly replacement?: string | ((match: string, context: BuildMethodContext) => string); readonly predicate?: (context: BuildMethodContext) => boolean; } /** * Method parameter definition */ interface MethodParameter { readonly name: string; readonly type: string; readonly isOptional?: boolean; readonly defaultValue?: string; } /** * Custom method definition for builder */ interface CustomMethodDefinition { readonly name: string; readonly parameters: readonly MethodParameter[]; readonly returnType: StaticOrDynamic<string, BuilderContext>; readonly implementation: StaticOrDynamic<string, BuilderContext>; readonly jsDoc?: string; readonly predicate?: (context: BuilderContext) => boolean; } /** * Re-export type transformation types from type-matcher */ type TypeTransformer = TypeTransformer$1; type TypeTransformContext = TypeTransformContext$1; //#endregion //#region src/core/plugin/plugin-import-manager.d.ts /** * Fluent API for managing plugin imports * Provides a type-safe way to declare import requirements without string manipulation */ declare class ImportManager { private imports; private normalizeImports; private buildImportOptions; /** * Add an internal project import * @param path - Relative path to the file * @param imports - Named imports from the file * @param options - Import options */ addInternal(path: string, imports: string | string[], options?: { typeOnly?: boolean; isDefault?: boolean; defaultName?: string; }): this; /** * Add an external package import * @param packageName - Name of the npm package * @param imports - Named imports from the package * @param options - Import options */ addExternal(packageName: string, imports: string | string[], options?: { typeOnly?: boolean; isDefault?: boolean; defaultName?: string; }): this; /** * Add a default import from an internal file * @param path - Relative path to the file * @param defaultName - Name for the default import */ addInternalDefault(path: string, defaultName: string): this; /** * Add a default import from an external package * @param packageName - Name of the npm package * @param defaultName - Name for the default import */ addExternalDefault(packageName: string, defaultName: string): this; /** * Add type-only imports from an internal file * @param path - Relative path to the file * @param types - Type names to import */ addInternalTypes(path: string, types: string | string[]): this; /** * Add type-only imports from an external package * @param packageName - Name of the npm package * @param types - Type names to import */ addExternalTypes(packageName: string, types: string | string[]): this; /** * Merge imports from another ImportManager into this one * @param other - Another ImportManager instance to merge from * @returns This ImportManager for chaining */ merge(other: ImportManager): this; getImports(): readonly Import[]; /** * Build the final plugin imports configuration * @returns PluginImports object containing all configured imports */ build(): PluginImports; /** * Convert imports to TypeScript/JavaScript import statements. * Internal imports are listed first, followed by external imports. * @returns Array of import statement strings ready for code generation */ toImportStatements(): string[]; private importsToStatements; /** * Convert a single import to an import statement */ private importToStatement; /** * Check if an import matching the predicate exists * @param predicate - Function to test each import * @returns True if at least one import matches */ hasImport(predicate: (imp: Import) => boolean): boolean; /** * Remove all imports matching the predicate * @param predicate - Function to test each import; returns true to remove * @returns This ImportManager for chaining */ removeImports(predicate: (imp: Import) => boolean): this; clear(): this; /** * Get imports grouped by kind (internal vs external) * @returns Object with internal and external import arrays */ getGroupedImports(): { internal: readonly InternalImport[]; external: readonly ExternalImport[]; }; /** * Deduplicate imports by merging those from the same source with compatible options. * Type-only and regular imports are kept separate, as are default and named imports. * Returns a new ImportManager instance with deduplicated imports. * * @returns A new ImportManager with deduplicated imports * @example * ```ts * const manager = new ImportManager() * .addInternal('./types.js', 'User') * .addInternal('./types.js', 'Product'); * const deduped = manager.deduplicate(); * // Results in single import: import { User, Product } from './types.js' * ``` */ deduplicate(): ImportManager; /** * Convert to PluginImports format * @deprecated Use build() instead */ toPluginImports(): PluginImports;