diff --git a/packages/jsii/bin/jsii.ts b/packages/jsii/bin/jsii.ts index 15ddbb8a69..802e99873b 100644 --- a/packages/jsii/bin/jsii.ts +++ b/packages/jsii/bin/jsii.ts @@ -64,6 +64,11 @@ const warningTypes = Object.keys(enabledWarnings); type: 'boolean', default: false, desc: '[EXPERIMENTAL] Injects warning statements for all deprecated elements, to be printed at runtime', + }) + .option('generate-tsconfig', { + type: 'string', + default: 'tsconfig.json', + desc: 'Name of the typescript configuration file to generate with compiler settings', }), ) .option('verbose', { @@ -108,6 +113,7 @@ const warningTypes = Object.keys(enabledWarnings); failOnWarnings: argv['fail-on-warnings'], stripDeprecated: argv['strip-deprecated'], addDeprecationWarnings: argv['add-deprecation-warnings'], + generateTypeScriptConfig: argv['generate-tsconfig'], }); const emitResult = await (argv.watch ? compiler.watch() : compiler.emit()); diff --git a/packages/jsii/lib/compiler.ts b/packages/jsii/lib/compiler.ts index 0a02b9d735..bb1098127f 100644 --- a/packages/jsii/lib/compiler.ts +++ b/packages/jsii/lib/compiler.ts @@ -54,6 +54,11 @@ export interface CompilerOptions { stripDeprecated?: boolean; /** Whether to add warnings for deprecated elements */ addDeprecationWarnings?: boolean; + /** + * The name of the tsconfig file to generate + * @default "tsconfig.json" + */ + generateTypeScriptConfig?: string; } export interface TypescriptConfig { @@ -79,9 +84,11 @@ export class Compiler implements Emitter { }, ); + const configFileName = options.generateTypeScriptConfig ?? 'tsconfig.json'; + this.configPath = path.join( this.options.projectInfo.projectRoot, - 'tsconfig.json', + configFileName, ); this.projectReferences = diff --git a/packages/jsii/test/compiler.test.ts b/packages/jsii/test/compiler.test.ts index 858637e90a..ae82311d9c 100644 --- a/packages/jsii/test/compiler.test.ts +++ b/packages/jsii/test/compiler.test.ts @@ -1,4 +1,4 @@ -import { mkdtemp, remove, writeFile, readFile } from 'fs-extra'; +import { mkdtemp, remove, writeFile, readFile, readJson } from 'fs-extra'; import { tmpdir } from 'os'; import { join } from 'path'; @@ -6,6 +6,40 @@ import { Compiler } from '../lib/compiler'; import { ProjectInfo } from '../lib/project-info'; describe(Compiler, () => { + describe('generated tsconfig', () => { + test('default is tsconfig.json', async () => { + const sourceDir = await mkdtemp( + join(tmpdir(), 'jsii-compiler-watch-mode-'), + ); + + const compiler = new Compiler({ + projectInfo: _makeProjectInfo(sourceDir, 'index.d.ts'), + }); + + await compiler.emit(); + + expect(await readJson(join(sourceDir, 'tsconfig.json'), 'utf-8')).toEqual( + expectedTypeScriptConfig(), + ); + }); + + test('file name can be customized', async () => { + const sourceDir = await mkdtemp( + join(tmpdir(), 'jsii-compiler-watch-mode-'), + ); + + const compiler = new Compiler({ + projectInfo: _makeProjectInfo(sourceDir, 'index.d.ts'), + generateTypeScriptConfig: 'tsconfig.jsii.json', + }); + + await compiler.emit(); + + expect( + await readJson(join(sourceDir, 'tsconfig.jsii.json'), 'utf-8'), + ).toEqual(expectedTypeScriptConfig()); + }); + }); test('"watch" mode', async () => { // This can be a little slow, allowing 15 seconds maximum here (default is 5 seconds) jest.setTimeout(15_000); @@ -91,3 +125,39 @@ function _makeProjectInfo(sourceDir: string, types: string): ProjectInfo { excludeTypescript: [], }; } + +function expectedTypeScriptConfig() { + return { + _generated_by_jsii_: + 'Generated by jsii - safe to delete, and ideally should be in .gitignore', + compilerOptions: { + alwaysStrict: true, + charset: 'utf8', + composite: false, + declaration: true, + experimentalDecorators: true, + incremental: true, + inlineSourceMap: true, + inlineSources: true, + lib: ['es2019'], + module: 'CommonJS', + newLine: 'lf', + noEmitOnError: true, + noFallthroughCasesInSwitch: true, + noImplicitAny: true, + noImplicitReturns: true, + noImplicitThis: true, + noUnusedLocals: true, + noUnusedParameters: true, + resolveJsonModule: true, + strict: true, + strictNullChecks: true, + strictPropertyInitialization: true, + stripInternal: false, + target: 'ES2019', + tsBuildInfoFile: 'tsconfig.tsbuildinfo', + }, + exclude: ['node_modules'], + include: [join('**', '*.ts')], + }; +}