Get AST after customTransformers.before without emit
- Dominant language
- TypeScript
- Stars
- 6.2k
- Forks
- 238
- Avg merge
- 2m
- Merged PRs (30d)
- 1
Description
**Is your feature request related to a problem? Please describe.**
I am trying to run [@nestjs/swagger](https://github.com/nestjs/swagger)'s plugin over TS files, and rather than emit the source directly, save the source over the original file.
I want to do this, because due to current tsc limitations, this plugin can't run with a normal "tsc" CLI call, which is what I use as part of my build chain, and I prefer not to switch to nest-cli, as that presents one more thing that can go wrong on build and in watch mode.
Working directly with the typescript API I get some runtime errors, which I tried to workaround with edits to @nestjs/swagger itself, but ultimately, I failed (I only kept trading in one error for another), so I thought I'd use ts-morph to abstract the weird stuff I'm apparently not using correctly.
However, even with ts-morph, I seem to be back at square 1, where I have the plugin, and I can't use it.
**Describe the solution you'd like**
ts-morph's SourceFile should provide another transform()-like method that should accept a tsc compatible "before" ```TransformerFactory``` or ```CustomTransformer```, and applies that, allowing further manipulations or just saves over the final files.
e.g. (tentatively calling it "transformWithCompiler"; whatever the name is, it's fine by me...)
```typescript
import { before } from '@nestjs/swagger/dist/plugin';
import { Project, SourceFile } from 'ts-morph';
const project = new Project({
tsConfigFilePath: 'path/to/tsconfig.json',
});
const swaggerTransformer = before({}, project.getProgram().compilerObject);
const saves: Array> = [];
project.getSourceFiles().forEach((file: SourceFile): void => {
saves.push(file.transformWithCompiler(swaggerTransformer).save());
});
Promise.all(saves).then(() => {
console.log('Done');
});
```
Alternatively, the ```TransformTraversalControl``` object could expose a ```ts.TransformerContext``` object. That would allow calling the "tsc" transformer from inside the transform function, e.g.
```typescript
import { before } from '@nestjs/swagger/dist/plugin';
import { Project, SourceFile } from 'ts-morph';
import { Node } from 'typescript';
const project = new Project({
tsConfigFilePath: 'path/to/tsconfig.json',
});
const swaggerTransformer = before({}, project.getProgram().compilerObject);
const saves: Array> = [];
project.getSourceFiles().forEach((file: SourceFile): void => {
saves.push(file.transform((ttc: TransformTraversalControl): Node => {
return swaggerTransformer(ttc.getCompilerTransformContext());
}).save());
});
Promise.all(saves).then(() => {
console.log('Done');
});
```
**Describe alternatives you've considered**
I tried
```typescript
import { before } from '@nestjs/swagger/dist/plugin';
import { Project, SourceFile } from 'ts-morph';
const project = new Project({
tsConfigFilePath: 'path/to/tsconfig.json',
});
const swaggerTransformer = before({}, project.getProgram().compilerObject);
const saves: Array> = [];
project.getSourceFiles().forEach((file: SourceFile): void => {
saves.push(file.transform(/*build error here*/swaggerTransformer).save());
});
Promise.all(saves).then(() => {
console.log('Done');
});
```
but that fails to compile, because the transform() method is using a custom API, not typescript's actual API.
The example at [the emitting page](https://ts-morph.com/emitting) doesn't work either, for the same reason - it's a transformer intended for "typescript", not "ts-morph".
Contributor guide
Assessment
This issue has not been assessed yet.