Skip to content

Commit

Permalink
Fix order of DEFAULTS, tsconfig, rawOptions
Browse files Browse the repository at this point in the history
  • Loading branch information
blakeembrey committed Jan 10, 2020
1 parent 9aa66ff commit db409d7
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 44 deletions.
19 changes: 16 additions & 3 deletions src/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,20 @@ describe('ts-node', function () {
describe('should read ts-node options from tsconfig.json', function () {
const BIN_EXEC = `node "${join(__dirname, '../dist/bin')}" --project tests/tsconfig-options/tsconfig.json`

it('options pulled from tsconfig.json', function (done) {
it('should override compiler options from env', function (done) {
exec(`${BIN_EXEC} tests/tsconfig-options/log-options.js`, {
env: {
TS_NODE_COMPILER_OPTIONS: '{"typeRoots": ["env-typeroots"]}'
}
}, function (err, stdout) {
expect(err).to.equal(null)
const { config } = JSON.parse(stdout)
expect(config.options.typeRoots).to.deep.equal([join(__dirname, '../tests/tsconfig-options/env-typeroots')])
return done()
})
})

it('should use options from `tsconfig.json`', function (done) {
exec(`${BIN_EXEC} tests/tsconfig-options/log-options.js`, function (err, stdout) {
expect(err).to.equal(null)
const { options, config } = JSON.parse(stdout)
Expand All @@ -365,7 +378,7 @@ describe('ts-node', function () {
})
})

it('flags override tsconfig', function (done) {
it('should have flags override `tsconfig.json`', function (done) {
exec(`${BIN_EXEC} --skip-ignore --compiler-options '{"types": ["flags-types"]}' tests/tsconfig-options/log-options.js`, function (err, stdout) {
expect(err).to.equal(null)
const { options, config } = JSON.parse(stdout)
Expand All @@ -378,7 +391,7 @@ describe('ts-node', function () {
})
})

it('tsconfig overrides env vars', function (done) {
it('should have `tsconfig.json` override environment', function (done) {
exec(`${BIN_EXEC} tests/tsconfig-options/log-options.js`, {
env: {
...process.env,
Expand Down
69 changes: 28 additions & 41 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,29 +195,16 @@ export interface TsConfigOptions extends Omit<RegisterOptions,
> {}

/**
* Like Object.assign or splatting, but never overwrites with `undefined`.
* This matches the behavior for argument and destructuring defaults.
* Like `Object.assign`, but ignores `undefined` properties.
*/
function defaults <T> (...sources: Array<T>): T {
const merged: T = Object.create(null)
function assign <T extends object> (initialValue: T, ...sources: Array<T>): T {
for (const source of sources) {
for (const key of Object.keys(source)) {
const value = (source as any)[key]
if (value !== undefined) (merged as any)[key] = value
if (value !== undefined) (initialValue as any)[key] = value
}
}
return merged
}

/**
* Like `defaults` but for single values, not objects.
*/
export function defaultValue <T> (...values: Array<T>): T | undefined {
let result: T | undefined = undefined
for (const value of values) {
if (value !== undefined) result = value
}
return result
return initialValue
}

/**
Expand Down Expand Up @@ -357,8 +344,9 @@ export function register (opts: RegisterOptions = {}): Register {
* Create TypeScript compiler instance.
*/
export function create (rawOptions: CreateOptions = {}): Register {
const inputOptions = defaults(DEFAULTS, rawOptions)
const cwd = inputOptions.dir ? resolve(inputOptions.dir) : process.cwd()
const dir = rawOptions.dir ?? DEFAULTS.dir
const compilerName = rawOptions.compiler ?? DEFAULTS.compiler
const cwd = dir ? resolve(dir) : process.cwd()

/**
* Load the typescript compiler. It is required to load the tsconfig but might
Expand All @@ -371,16 +359,14 @@ export function create (rawOptions: CreateOptions = {}): Register {
}

// Compute minimum options to read the config file.
let { compiler, ts } = loadCompiler(inputOptions.compiler)
let { compiler, ts } = loadCompiler(compilerName)

// Read config file.
// Read config file and merge new options between env and CLI options.
const { config, options: tsconfigOptions } = readConfig(cwd, ts, rawOptions)

// Merge default options, tsconfig options, and explicit options.
const options = defaults<CreateOptions>(DEFAULTS, tsconfigOptions || {}, rawOptions)
const options = assign<CreateOptions>({}, DEFAULTS, tsconfigOptions || {}, rawOptions)

// If `compiler` option changed based on tsconfig, re-load the compiler.
if (options.compiler !== inputOptions.compiler) {
if (options.compiler !== compilerName) {
({ compiler, ts } = loadCompiler(options.compiler))
}

Expand Down Expand Up @@ -850,18 +836,18 @@ function fixConfig (ts: TSCommon, config: _ts.ParsedCommandLine) {
}

/**
* Load TypeScript configuration. Returns both a parsed typescript config and
* any ts-node options specified in the config file.
* Load TypeScript configuration. Returns the parsed TypeScript config and
* any `ts-node` options specified in the config file.
*/
function readConfig (
cwd: string,
ts: TSCommon,
options: CreateOptions
rawOptions: CreateOptions
): {
/** Parsed TypeScript configuration */
// Parsed TypeScript configuration.
config: _ts.ParsedCommandLine
/** ts-node options pulled from tsconfig */
options?: TsConfigOptions
// Options pulled from `tsconfig.json`.
options: TsConfigOptions
} {
let config: any = { compilerOptions: {} }
let basePath = cwd
Expand All @@ -872,7 +858,7 @@ function readConfig (
readFile = ts.sys.readFile,
skipProject = DEFAULTS.skipProject,
project = DEFAULTS.project
} = options
} = rawOptions

// Read project configuration when available.
if (!skipProject) {
Expand All @@ -885,7 +871,10 @@ function readConfig (

// Return diagnostics.
if (result.error) {
return { config: { errors: [result.error], fileNames: [], options: {} } }
return {
config: { errors: [result.error], fileNames: [], options: {} },
options: {}
}
}

config = result.config
Expand All @@ -894,24 +883,22 @@ function readConfig (
}

// Fix ts-node options that come from tsconfig.json
const tsconfigOptions: TsConfigOptions = {
...config['ts-node']
}
const tsconfigOptions: TsConfigOptions = Object.assign({}, config['ts-node'])

// Remove resolution of "files".
const filesOption = defaultValue(DEFAULTS.files, tsconfigOptions.files, options.files)
if (!filesOption) {
const files = rawOptions.files ?? tsconfigOptions.files ?? DEFAULTS.files
if (!files) {
config.files = []
config.include = []
}

// Override default configuration options `ts-node` requires.
config.compilerOptions = Object.assign(
{},
DEFAULTS.compilerOptions,
config.compilerOptions,
config['ts-node']?.compilerOptions,
options.compilerOptions,
DEFAULTS.compilerOptions,
tsconfigOptions.compilerOptions,
rawOptions.compilerOptions,
TS_NODE_COMPILER_OPTIONS
)

Expand Down

0 comments on commit db409d7

Please sign in to comment.