Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#1100: adds --show-config to log the resolved configuration #1243

Merged
merged 4 commits into from Feb 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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 @@ -134,14 +134,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 @@ -430,6 +439,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 @@ -1051,7 +1062,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