Skip to content

Plugin API Quick Reference

Quick Lookup This page is your quick reference. For detailed

explanations, see the main guide sections. :::

Plugin Builder API

Creating a Plugin

typescript
import { createPlugin } from 'fluent-gen-ts';

const plugin = createPlugin(name: string, version: string)
  .setDescription(description: string)
  .requireImports(configurator: (manager) => manager)
  .transformPropertyMethods(configurator: (builder) => builder)
  .addMethod(configurator: (builder) => builder)
  .transformBuildMethod(configurator: (builder) => builder)
  // ... other methods
  .build();

Metadata

MethodParametersDescription
createPluginname: string, version: stringStart building a plugin
.setDescriptiondescription: stringSet plugin description

Import Management

MethodParametersDescription
.requireImportsconfigurator: (imports) => importsAdd required imports
imports.addExternalpkg: string, names: string[]Import from package
imports.addInternalpath: string, names: string[]Import from local file
imports.addExternalTypespkg: string, types: string[]Import types from package
imports.addInternalTypespath: string, types: string[]Import types from file

Property Transformations

MethodParametersDescription
.transformPropertyMethodsconfigurator: (builder) => builderTransform property methods
builder.whenpredicate: (ctx) => booleanCondition for transformation
builder.setParametertype: string | functionSet parameter type
builder.setExtractorcode: stringSet value extraction code
builder.setValidatorcode: stringSet validation code
builder.done()Complete current rule

Context Object (ctx):

typescript
{
  property: PropertyInfo;        // Property metadata
  propertyType: TypeInfo;        // Property type info
  type: TypeMatcherInterface;    // Type matcher
  typeName: string;              // Builder type name
  builderName: string;           // Builder class name
  originalTypeString: string;    // Original type as string
  isOptional(): boolean;         // Check if optional
  isReadonly(): boolean;         // Check if readonly
}

Custom Methods

MethodParametersDescription
.addMethodconfigurator: (method) => methodAdd custom method
method.whenpredicate: (ctx) => booleanCondition for method
method.namename: stringSet method name
method.parametername: string, type: string, options?Add parameter
method.returnstype: string | functionSet return type
method.implementationcode: string | functionSet method body
method.jsDocdoc: stringAdd JSDoc comment

Context Object (ctx):

typescript
{
  builderName: string;           // Builder class name
  typeName: string;              // Type being built
  properties: PropertyInfo[];    // All properties
  typeInfo: TypeInfo;            // Type information
  genericParams: string;         // Generic parameters
  genericConstraints: string;    // Generic constraints
  hasProperty(name: string): boolean;
  getProperty(name: string): PropertyInfo | undefined;
  getRequiredProperties(): PropertyInfo[];
  getOptionalProperties(): PropertyInfo[];
}

Build Method Transformation

MethodParametersDescription
.transformBuildMethodconfigurator: (transform) => transformTransform build method
transform.whenpredicate: (ctx) => booleanCondition for transform
transform.insertBeforemarker: string, code: stringInsert before marker
transform.insertAftermarker: string, code: stringInsert after marker
transform.replacemarker: string, code: stringReplace marker
transform.wrapMethodbefore: string, after: stringWrap method

Context Object (ctx):

typescript
{
  buildMethodCode: string;       // Current build method code
  builderName: string;           // Builder class name
  typeName: string;              // Type being built
  properties: PropertyInfo[];    // All properties
  options: GeneratorOptions;     // Generator options
  resolvedType: ResolvedType;    // Resolved type info
}

Common markers:

  • 'return this.buildWithDefaults' - Before final return
  • 'const result =' - After build completes
  • 'return {' - Start of return statement

Type Matcher API

Import matchers:

typescript
import {
  primitive,
  object,
  array,
  union,
  intersection,
  reference,
  generic,
  literal,
} from 'fluent-gen-ts';

Primitive Types

typescript
primitive(...names: string[])

// Examples:
primitive('string')
primitive('number', 'string')  // Match multiple

Object Types

typescript
object(name?: string)
  .withGeneric(name?: string)
  .withProperty(name: string, type?: TypeMatcher)
  .withProperties(...names: string[])

// Examples:
object('User')
object().withProperty('email', primitive('string'))
object('User').withGeneric()

Array Types

typescript
array().of(matcher: TypeMatcher)

// Examples:
array()
array().of(primitive('string'))
array().of(object('User'))

Union Types

typescript
union()
  .containing(matcher: TypeMatcher)
  .exact(...matchers: TypeMatcher[])

// Examples:
union().containing(primitive('null'))
union().exact(primitive('string'), primitive('number'))

Intersection Types

typescript
intersection()
  .including(matcher: TypeMatcher)
  .exact(...matchers: TypeMatcher[])

Other Matchers

typescript
reference(name?: string)     // Type reference
generic(name?: string)       // Generic type
literal(value: any)          // Literal value
any()                        // Any type
never()                      // Never type

// Logical operators
or(...matchers)              // Match any
and(...matchers)             // Match all
not(matcher)                 // Negate match

Type Checker (Context)

Available on ctx.type:

MethodReturnsDescription
.isPrimitive(...names)booleanMatch primitive types
.isObject(name?)ObjectTypeMatcherMatch object types
.isArray()ArrayTypeMatcherMatch arrays
.isUnion()UnionTypeMatcherMatch unions
.isIntersection()IntersectionTypeMatcherMatch intersections
.isReference(name?)booleanMatch type references
.isGeneric(name?)booleanMatch generic types
.matches(matcher)booleanMatch any matcher
.toString()stringType as string

Deep Type Transformations

Transform Deep

typescript
transformTypeDeep(typeInfo: TypeInfo, transformer: TypeTransformer)

// Transformer interface:
{
  onPrimitive?: (type) => string | TypeInfo | null;
  onObject?: (type) => string | TypeInfo | null;
  onArray?: (type) => string | TypeInfo | null;
  onUnion?: (type) => string | TypeInfo | null;
  // ... etc
}

TypeDeepTransformer (Fluent API)

typescript
new TypeDeepTransformer(typeInfo)
  .replace(matcher: TypeMatcher, replacement: string | function)
  .replaceIf(predicate: function, replacement: string | function)
  .hasMatch(matcher: TypeMatcher): boolean
  .findMatches(matcher: TypeMatcher): TypeInfo[]
  .toString(): string

// Example:
ctx.type.transformDeep()
  .replace(primitive('string'), 'string | TaggedValue<string>')
  .toString()

Utility Functions

typescript
typeInfoToString(typeInfo: TypeInfo): string
containsTypeDeep(typeInfo: TypeInfo, matcher: TypeMatcher): boolean
findTypesDeep(typeInfo: TypeInfo, matcher: TypeMatcher): TypeInfo[]

Lifecycle Hooks

HookWhenParametersReturns
beforeParseBefore parsing fileParseContextParseContext
afterParseAfter parsingParseContext, TypeType
beforeResolveBefore type resolutionResolveContextResolveContext
afterResolveAfter resolutionResolveContext, TypeInfoTypeInfo
beforeGenerateBefore code generationGenerateContextGenerateContext
transformPropertyPer propertyPropertyInfoPropertyInfo
transformTypePer typeType, TypeInfoTypeInfo
afterGenerateAfter generationcode: string, contextstring

TypeInfo Structure

typescript
interface TypeInfo {
  kind: TypeKind; // Type category
  name?: string; // Type name
  properties?: PropertyInfo[]; // Object properties
  elementType?: TypeInfo; // Array element type
  types?: TypeInfo[]; // Union/Intersection types
  genericParams?: TypeInfo[]; // Generic parameters
  value?: any; // Literal value
}

enum TypeKind {
  Primitive = 'primitive',
  Object = 'object',
  Array = 'array',
  Union = 'union',
  Intersection = 'intersection',
  Reference = 'reference',
  Generic = 'generic',
  Literal = 'literal',
  Any = 'any',
  Never = 'never',
}

PropertyInfo Structure

typescript
interface PropertyInfo {
  name: string; // Property name
  type: TypeInfo; // Property type
  optional: boolean; // Is optional?
  readonly: boolean; // Is readonly?
  jsDoc?: string; // JSDoc comment
}

Common Patterns

Email Validation

typescript
.when(ctx => ctx.property.name === 'email')
.setValidator('if (value && !isEmail(value)) throw new Error("Invalid")')

Type Transformation

typescript
.when(ctx => ctx.property.name.endsWith('Id'))
.setParameter('string | number')
.setExtractor('String(value)')

Conditional Custom Method

typescript
.addMethod(method => method
  .when(ctx => ctx.builderName === 'UserBuilder')
  .name('withFakeEmail')
  .returns('this')
  .implementation('return this.email("fake@example.com");')
)

Conditional Build Hook

typescript
.transformBuildMethod(transform =>
  transform
    .when(ctx => ctx.builderName === 'UserBuilder')
    .insertBefore('return {', 'this.validate();')
)

Custom Method (unconditional)

typescript
.addMethod(method => method
  .name('withDefaults')
  .returns('this')
  .implementation('/* set default values */')
)

Deep Transform

typescript
.when(ctx => ctx.type.containsDeep(primitive('string')))
.setParameter(ctx => ctx.type.transformDeep()
  .replace(primitive('string'), 'string | Tagged<string>')
  .toString()
)

Error Handling

typescript
import { Result, ok, err } from 'fluent-gen-ts';

// Result type
type Result<T> =
  | { ok: true; value: T }
  | { ok: false; error: Error };

// Helpers
ok<T>(value: T): Result<T>
err<T>(error: Error): Result<T>

Testing

typescript
// Unit test
expect(plugin.name).toBe('my-plugin');
expect(plugin.transformPropertyMethod).toBeDefined();

// Integration test
const user = user().withEmail('test@example.com').build();
expect(user.email).toBe('test@example.com');

Rule Ordering

CRITICAL First matching rule wins! Always place specific rules

before generic ones:

typescript
.when(ctx => ctx.type.matches(object('AssetWrapper')))  // Specific FIRST
.done()
.when(ctx => ctx.type.containsDeep(primitive('string'))) // Generic LAST

Next Steps

Released under the MIT License.