Skip to content

Commit

Permalink
#1100: adds --show-config to log the resolved configuration (#1243)
Browse files Browse the repository at this point in the history
* add --show-config which is like a ts-node equivalent of tsc --showConfig

* fix and add tests

* try to fix test

* fix tests and sneak in an update to ts 4.2 since it affects the output
of --showConfig
  • Loading branch information
cspotcode committed Feb 24, 2021
1 parent 9e34e18 commit 4e04302
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 10 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -123,7 +123,7 @@
"tslint": "^6.1.0",
"tslint-config-standard": "^9.0.0",
"typedoc": "^0.20.20",
"typescript": "4.1.2",
"typescript": "4.2.2",
"typescript-json-schema": "^0.42.0",
"util.promisify": "^1.0.1"
},
Expand Down
30 changes: 28 additions & 2 deletions src/bin.ts
Expand Up @@ -10,7 +10,7 @@ import {
createRepl,
ReplService
} from './repl'
import { VERSION, TSError, parse, register, createRequire } from './index'
import { VERSION, TSError, parse, register, createRequire, TSInternal } from './index'

/**
* Main `bin` functionality.
Expand All @@ -30,6 +30,7 @@ export function main (argv: string[] = process.argv.slice(2), entrypointArgs: Re
'--cwd-mode': Boolean,
'--script-mode': Boolean,
'--version': arg.COUNT,
'--show-config': Boolean,

// Project options.
'--cwd': String,
Expand Down Expand Up @@ -64,7 +65,8 @@ export function main (argv: string[] = process.argv.slice(2), entrypointArgs: Re
'-C': '--compiler',
'-D': '--ignore-diagnostics',
'-O': '--compiler-options',
'--dir': '--cwd'
'--dir': '--cwd',
'--showConfig': '--show-config'
}, {
argv,
stopAtPositional: true
Expand All @@ -80,6 +82,7 @@ export function main (argv: string[] = process.argv.slice(2), entrypointArgs: Re
'--script-mode': scriptMode,
'--cwd-mode': cwdMode,
'--version': version = 0,
'--show-config': showConfig,
'--require': argsRequire = [],
'--eval': code = undefined,
'--print': print = false,
Expand Down Expand Up @@ -115,6 +118,7 @@ export function main (argv: string[] = process.argv.slice(2), entrypointArgs: Re
-h, --help Print CLI usage
-v, --version Print module version information
--cwd-mode Use current directory instead of <script.ts> for config resolution
--show-config Print resolved configuration and exit
-T, --transpile-only Use TypeScript's faster \`transpileModule\`
-H, --compiler-host Use TypeScript's compiler host API
Expand Down Expand Up @@ -184,6 +188,28 @@ export function main (argv: string[] = process.argv.slice(2), entrypointArgs: Re
process.exit(0)
}

if (showConfig) {
const ts = service.ts as any as TSInternal
if (typeof ts.convertToTSConfig !== 'function') { // tslint:disable-line:strict-type-predicates
console.error('Error: --show-config requires a typescript versions >=3.2 that support --showConfig')
process.exit(1)
}
const json = ts.convertToTSConfig(service.config, service.configFilePath ?? join(cwd, 'ts-node-implicit-tsconfig.json'), service.ts.sys)
json['ts-node'] = {
...service.options,
experimentalEsmLoader: undefined,
compilerOptions: undefined,
project: service.configFilePath ?? service.options.project
}
console.log(
// Assumes that all configuration options which can possibly be specified via the CLI are JSON-compatible.
// If, in the future, we must log functions, for example readFile and fileExists, then we can implement a JSON
// replacer function.
JSON.stringify(json, null, 2)
)
process.exit(0)
}

// Create a local module instance based on `cwd`.
const module = new Module(state.path)
module.filename = state.path
Expand Down
42 changes: 41 additions & 1 deletion src/index.spec.ts
@@ -1,7 +1,7 @@
import { test, TestInterface } from './testlib'
import { expect } from 'chai'
import { ChildProcess, exec as childProcessExec, ExecException, ExecOptions } from 'child_process'
import { join } from 'path'
import { join, resolve, sep as pathSep } from 'path'
import semver = require('semver')
import ts = require('typescript')
import proxyquire = require('proxyquire')
Expand Down Expand Up @@ -35,6 +35,7 @@ function exec (cmd: string, opts: ExecOptions = {}): Promise<TestExecReturn> & {
)
}

const ROOT_DIR = resolve(__dirname, '..')
const TEST_DIR = join(__dirname, '../tests')
const PROJECT = join(TEST_DIR, 'tsconfig.json')
const BIN_PATH = join(TEST_DIR, 'node_modules/.bin/ts-node')
Expand Down Expand Up @@ -583,6 +584,45 @@ test.suite('ts-node', (test) => {
)
})
})

if (semver.gte(ts.version, '3.2.0')) {
test('--show-config should log resolved configuration', async (t) => {
function native (path: string) { return path.replace(/\/|\\/g, pathSep) }
function posix (path: string) { return path.replace(/\/|\\/g, '/') }
const { err, stdout } = await exec(`${cmd} --showConfig`)
expect(err).to.equal(null)
t.is(stdout, JSON.stringify({
'compilerOptions': {
'target': 'es6',
'jsx': 'react',
'noEmit': false,
'strict': true,
'typeRoots': [
posix(`${ ROOT_DIR }/tests/typings`),
posix(`${ ROOT_DIR }/node_modules/@types`)
],
'sourceMap': true,
'inlineSourceMap': false,
'inlineSources': true,
'declaration': false,
'outDir': './.ts-node',
'module': 'commonjs'
},
'ts-node': {
'cwd': native(`${ ROOT_DIR }/tests`),
'projectSearchDir': native(`${ ROOT_DIR }/tests`),
'project': native(`${ ROOT_DIR }/tests/tsconfig.json`),
'require': []
}
}, null, 2) + '\n')
})
} else {
test('--show-config should log error message when used with old typescript versions', async (t) => {
const { err, stderr } = await exec(`${cmd} --showConfig`)
expect(err).to.not.equal(null)
expect(stderr).to.contain('Error: --show-config requires')
})
}
})

test.suite('register', (_test) => {
Expand Down
17 changes: 14 additions & 3 deletions src/index.ts
Expand Up @@ -135,14 +135,23 @@ export interface TSCommon {

/**
* Compiler APIs we use that are marked internal and not included in TypeScript's public API declarations
* @internal
*/
interface TSInternal {
export interface TSInternal {
// https://github.com/microsoft/TypeScript/blob/4a34294908bed6701dcba2456ca7ac5eafe0ddff/src/compiler/core.ts#L1906-L1909
createGetCanonicalFileName (useCaseSensitiveFileNames: boolean): TSInternal.GetCanonicalFileName
// https://github.com/microsoft/TypeScript/blob/c117c266e09c80e8a06b24a6e94b9d018f5fae6b/src/compiler/commandLineParser.ts#L2054
convertToTSConfig (configParseResult: _ts.ParsedCommandLine, configFileName: string, host: TSInternal.ConvertToTSConfigHost): any
}
namespace TSInternal {
/** @internal */
export namespace TSInternal {
// https://github.com/microsoft/TypeScript/blob/4a34294908bed6701dcba2456ca7ac5eafe0ddff/src/compiler/core.ts#L1906
export type GetCanonicalFileName = (fileName: string) => string
// https://github.com/microsoft/TypeScript/blob/c117c266e09c80e8a06b24a6e94b9d018f5fae6b/src/compiler/commandLineParser.ts#L2041
export interface ConvertToTSConfigHost {
getCurrentDirectory (): string
useCaseSensitiveFileNames: boolean
}
}

/**
Expand Down Expand Up @@ -432,6 +441,8 @@ export interface Service {
ignored (fileName: string): boolean
compile (code: string, fileName: string, lineOffset?: number): string
getTypeInfo (code: string, fileName: string, position: number): TypeInfo
/** @internal */
configFilePath: string | undefined
}

/**
Expand Down Expand Up @@ -1053,7 +1064,7 @@ export function create (rawOptions: CreateOptions = {}): Service {
return true
}

return { ts, config, compile, getTypeInfo, ignored, enabled, options }
return { ts, config, compile, getTypeInfo, ignored, enabled, options, configFilePath }
}

/**
Expand Down

0 comments on commit 4e04302

Please sign in to comment.