Skip to content

Commit

Permalink
feat: synthesize esbuild types from source
Browse files Browse the repository at this point in the history
  • Loading branch information
Momo Kornher committed Oct 22, 2021
1 parent bfa33b6 commit e261d46
Show file tree
Hide file tree
Showing 11 changed files with 166 additions and 453 deletions.
9 changes: 3 additions & 6 deletions .eslintrc.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .gitattributes

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .projen/deps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions .projen/tasks.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 31 additions & 26 deletions .projenrc.mjs → .projenrc.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
import { readFileSync } from 'fs';
import { ESLint } from 'eslint';
import {
AwsCdkConstructLibrary,
JsonFile,
NodePackageManager,
release,
TextFile,
vscode,
} from 'projen';
import { SourceFile } from 'ts-morph';
import { TypeScriptSourceFile } from './projenrc/TypeScriptSourceFile';

const project = new AwsCdkConstructLibrary({
projenrcTs: true,
projenrcTsOptions: {
filename: '.projenrc.mjs',
filename: '.projenrc.ts',
},
eslintOptions: {
lintProjenRc: false,
fileExtensions: ['.ts', '.tsx', '.mjs'],
dirs: ['src', '.projenrc.mjs'],
dirs: ['src', 'projenrc', '.projenrc.ts'],
},

// Project info
Expand Down Expand Up @@ -78,6 +76,7 @@ const project = new AwsCdkConstructLibrary({
devDeps: [
'@types/eslint',
'esbuild@^0.13.0',
'ts-morph',
],

// Ignore files
Expand Down Expand Up @@ -106,37 +105,21 @@ const project = new AwsCdkConstructLibrary({
});

const packageJson = project.tryFindObjectFile('package.json');
packageJson.addOverride('optionalDependencies', {
packageJson?.addOverride('optionalDependencies', {
esbuild: '^0.13.0',
});
packageJson.addOverride('jest.testPathIgnorePatterns.1', '/examples/');
packageJson?.addOverride('jest.testPathIgnorePatterns.1', '/examples/');

const eslintRc = project.tryFindObjectFile('.eslintrc.json');
eslintRc.addOverride('parserOptions.extraFileExtensions', ['.mjs']);
eslintRc.addOverride('ignorePatterns', [
eslintRc?.addOverride('ignorePatterns', [
'*.js',
'*.d.ts',
'node_modules/',
'*.generated.ts',
'coverage',
'!.projenrc.mjs',
'!.projenrc.ts',
]);

const linter = new ESLint({ fix: true });
const esbuildTypes = (
await linter.lintText(
readFileSync('node_modules/esbuild/lib/main.d.ts').toString(),
{
filePath: 'src/esbuild-types-raw.ts',
},
)
).pop().output;

new TextFile(project, 'src/esbuild-types-raw.ts', {
editGitignore: false,
lines: [esbuildTypes],
});

new JsonFile(project, '.vscode/extensions.json', {
readonly: false,
marker: false,
Expand Down Expand Up @@ -172,4 +155,26 @@ new vscode.VsCode(project).launchConfiguration.addConfiguration({
args: ['--runInBand', '--watchAll=false'],
});


new TypeScriptSourceFile(project, 'src/esbuild-types.ts', {
source: 'node_modules/esbuild/lib/main.d.ts',
editGitignore: false,
transformer: (esbuildTypes: SourceFile) => {
const readonlyInterface = (name: string) => {
esbuildTypes.getInterface(name)?.getProperties().forEach(property => property.setIsReadonly(true));
};

const removeFromInterface = (name: string, properties: string[]) => {
const interfaceDeclaration = esbuildTypes.getInterface(name);

properties.forEach(property => interfaceDeclaration?.getProperty(property)?.remove());
};


['CommonOptions', 'BuildOptions', 'TransformOptions'].forEach(readonlyInterface);
removeFromInterface('BuildOptions', ['entryPoints', 'stdin', 'plugins', 'watch']);
esbuildTypes.getInterface('TransformOptions')?.getProperty('tsconfigRaw')?.setType('string');
},
});

project.synth();
69 changes: 69 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 50 additions & 0 deletions projenrc/TypeScriptSourceFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { FileBase, FileBaseOptions, Project as ProjenProject } from 'projen';
import { execCapture } from 'projen/lib/util';
import { Project, SourceFile } from 'ts-morph';

interface TypeScriptSourceFileOptions extends Omit<FileBaseOptions, 'readonly'> {
source: string;
transformer?: (sourcefile: SourceFile) => void;
format?: boolean;
marker?: boolean;
}

export class TypeScriptSourceFile extends FileBase {
public readonly options: TypeScriptSourceFileOptions;

constructor(project: ProjenProject, filePath: string, options: TypeScriptSourceFileOptions) {
super(project, filePath, { ...options, readonly: false });

this.options = {
format: true,
marker: true,
...options,
};
}

protected synthesizeContent(): string {
const tsProject = new Project({
tsConfigFilePath: 'tsconfig.json',
skipAddingFilesFromTsConfig: true,
});

const sourceFile = tsProject.addSourceFileAtPath(this.options.source);

if (this.options.transformer) {
this.options.transformer(sourceFile);
}

return [
...(this.options.marker ? [`// ${TypeScriptSourceFile.PROJEN_MARKER}`] : []),
'',
sourceFile.getFullText(),
].join('\n');
}

public postSynthesize() {
super.postSynthesize();

const outdir = this.project.outdir;
execCapture(`npx eslint --ext .ts --fix ${this.absolutePath}`, { cwd: outdir });
}
}
Loading

0 comments on commit e261d46

Please sign in to comment.