simple-ts-transform

Library to help create simple typescript transformers

simple-ts-transform - Library to help create simple typescript transformers

This package provides a simple API to build TypeScript transformers, based on a shared context and multiple node visitors.

For usage examples, you can look at:

You may also be interrested in:

Language/langue

Because Slune is French firm, you will find all documents and messages in French. Other translations are welcome.

Anyway, because English is the language of programming, the code, including variable names and comments, are in English.

:fr: Une version française de ce document se trouve ici.

Installation

Installation is done using npm install command:

$ npm install --save simple-ts-transform

If you prefer using yarn:

$ yarn add simple-ts-transform
Usage

Context

First, create the context class. You can put in it whatever you need for your visitors. The context is created when the compilation starts and is updated for each file. Your node visitors can access the context, and of course, can also modify it if needed.

The context class constructor will be called with:

  • a ts.Program parameter,
  • an any object containing the configuration provided to the transformer.

The context class must also implement the initNewFile(context: TransformationContext, sourceFile: SourceFile): void method, called before visiting each new file.

// MyContext.ts
import { NodeVisitorContext } from 'simple-ts-transform'
import { Program, SourceFile, TransformationContext } from 'typescript'

export default class MyContext implements NodeVisitorContext {
  public readonly basePath: string
  public fileName?: string
  public constructor(program: Program, public readonly configuration: any) {
    this.basePath = program.getCompilerOptions().rootDir || program.getCurrentDirectory()
  }
  public initNewFile(_context: TransformationContext, sourceFile: SourceFile): void {
    this.fileName = sourceFile.fileName
  }
}

Node visitors

Then, you can create the node visitors. The node visitors are created for each file after the context is initialized and before starting the visit.

Because each node visitor is only managing one single type of node, this node type must be given as generic parameter N to the implemented interface.

The visitor constructor will be called with your context as single parameter.

Your visitor must implement the following methods:

  • The method wants(node: Node): node is N make some basic checkings on the node to indicate if the visitor will manage it or not. This method also serves as a type guard to ensure the node is of appropriate type.
  • The method visit(node: N): Node[] is given the node to visit in order to work on it. This method returns an array of 0, 1 or more nodes, so it can remove, update or create nodes. The nodes created by this visitor will be visited by all the following provided visitors.
// MyFileNameInserter.ts
import { NodeVisitor } from 'simple-ts-transform'
import { Node, StringLiteral } from 'typescript'

export default class MyFileNameInserter implements NodeVisitor<StringLiteral> {
  private readonly fileName: string
  public constructor(private readonly context: MyContext) {
    this.fileName = context.fileName!
  }
  public wants(node: Node): node is StringLiteral {
    return isStringLiteral(node)
  }
  public visit(node: StringLiteral) {
    return [createStringLiteral(this.fileName + ': ' + node.getText().slice(1, -1)]
  }
}

Transformer

You finally can create the transformer. For this, simply call buildTransformer and provide the context class and the node visitors in the order they have to be executed.

// index.ts
import buildTransformer from 'simple-ts-transform'
import MyContext from './MyContext'
import MyFileNameInserter from './MyFileNameInserter'
import OtherVisitor from './OtherVisitor'

const transformer = buildTransformer(MyContext, [MyFileNameInserter, OtherVisitor])
export default transformer

Repository

https://github.com/slune-org/simple-ts-transform.git