Skip to content

Commit

Permalink
fix: handle non-existent tsconfig
Browse files Browse the repository at this point in the history
  • Loading branch information
mdonnalley committed Nov 3, 2023
1 parent 026f835 commit 0b15536
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 13 deletions.
11 changes: 7 additions & 4 deletions src/config/ts-node.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import {readFile} from 'node:fs/promises'
import {join, relative as pathRelative, sep} from 'node:path'
import * as TSNode from 'ts-node'

import {memoizedWarn} from '../errors'
import {Plugin, TSConfig} from '../interfaces'
import {settings} from '../settings'
import {existsSync} from '../util/fs'
import {existsSync, safeReadFile} from '../util/fs'
import {isProd} from '../util/util'
import Cache from './cache'
import {Debug} from './util'
Expand Down Expand Up @@ -38,11 +37,15 @@ function importTypescript(root: string) {
async function loadTSConfig(root: string): Promise<TSConfig | undefined> {
try {
if (TS_CONFIGS[root]) return TS_CONFIGS[root]
const tsconfigPath = join(root, 'tsconfig.json')

const typescript = importTypescript(root)
if (!typescript) return

const {config} = typescript.parseConfigFileTextToJson(tsconfigPath, await readFile(tsconfigPath, 'utf8'))
const tsconfigPath = join(root, 'tsconfig.json')
const raw = await safeReadFile(tsconfigPath)
if (!raw) return

const {config} = typescript.parseConfigFileTextToJson(tsconfigPath, raw)

if (!config || Object.keys(config.compilerOptions).length === 0) return

Expand Down
12 changes: 12 additions & 0 deletions src/util/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,24 @@ export function readJsonSync<T = unknown>(path: string, parse = true): T | strin
return parse ? (JSON.parse(contents) as T) : contents
}

/**
* Read a JSON file, returning undefined if the file does not exist.
*/
export async function safeReadJson<T>(path: string): Promise<T | undefined> {
try {
return await readJson<T>(path)
} catch {}
}

/**
* Read a file, returning undefined if the file does not exist.
*/
export async function safeReadFile(path: string): Promise<string | undefined> {
try {
return await readFile(path, 'utf8')
} catch {}
}

export function existsSync(path: string): boolean {
return fsExistsSync(path)
}
18 changes: 9 additions & 9 deletions test/config/ts-node.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {expect} from 'chai'
import fs from 'node:fs/promises'
import {join, resolve} from 'node:path'
import {SinonSandbox, createSandbox} from 'sinon'
import * as tsNode from 'ts-node'

import * as configTsNode from '../../src/config/ts-node'
import {Interfaces, settings} from '../../src/index'
import * as util from '../../src/util/fs'

const root = resolve(__dirname, 'fixtures/typescript')
const tsSource = 'src/hooks/init.ts'
Expand Down Expand Up @@ -42,25 +42,25 @@ describe('tsPath', () => {
})

it('should resolve a .js file to ts src', async () => {
sandbox.stub(fs, 'readFile').resolves(JSON.stringify(DEFAULT_TS_CONFIG))
sandbox.stub(util, 'safeReadFile').resolves(JSON.stringify(DEFAULT_TS_CONFIG))
const result = await configTsNode.tsPath(root, jsCompiled)
expect(result).to.equal(join(root, tsModule))
})

it('should resolve a module file to ts src', async () => {
sandbox.stub(fs, 'readFile').resolves(JSON.stringify(DEFAULT_TS_CONFIG))
sandbox.stub(util, 'safeReadFile').resolves(JSON.stringify(DEFAULT_TS_CONFIG))
const result = await configTsNode.tsPath(root, jsCompiledModule)
expect(result).to.equal(join(root, tsModule))
})

it('should resolve a .ts file', async () => {
sandbox.stub(fs, 'readFile').resolves(JSON.stringify(DEFAULT_TS_CONFIG))
sandbox.stub(util, 'safeReadFile').resolves(JSON.stringify(DEFAULT_TS_CONFIG))
const result = await configTsNode.tsPath(root, tsSource)
expect(result).to.equal(join(root, tsSource))
})

it('should resolve a .ts file using baseUrl', async () => {
sandbox.stub(fs, 'readFile').resolves(
sandbox.stub(util, 'safeReadFile').resolves(
JSON.stringify({
compilerOptions: {
baseUrl: '.src/',
Expand All @@ -73,19 +73,19 @@ describe('tsPath', () => {
})

it('should resolve .ts with no outDir', async () => {
sandbox.stub(fs, 'readFile').resolves(JSON.stringify({compilerOptions: {rootDir: 'src'}}))
sandbox.stub(util, 'safeReadFile').resolves(JSON.stringify({compilerOptions: {rootDir: 'src'}}))
const result = await configTsNode.tsPath(root, tsSource)
expect(result).to.equal(join(root, tsSource))
})

it('should resolve .js with no rootDir and outDir', async () => {
sandbox.stub(fs, 'readFile').resolves(JSON.stringify({compilerOptions: {strict: true}}))
sandbox.stub(util, 'safeReadFile').resolves(JSON.stringify({compilerOptions: {strict: true}}))
const result = await configTsNode.tsPath(root, jsCompiled)
expect(result).to.equal(join(root, jsCompiled))
})

it('should resolve to .ts file if enabled and prod', async () => {
sandbox.stub(fs, 'readFile').resolves(JSON.stringify(DEFAULT_TS_CONFIG))
sandbox.stub(util, 'safeReadFile').resolves(JSON.stringify(DEFAULT_TS_CONFIG))
settings.tsnodeEnabled = true
const originalNodeEnv = process.env.NODE_ENV
delete process.env.NODE_ENV
Expand All @@ -98,7 +98,7 @@ describe('tsPath', () => {
})

it('should resolve to js if disabled', async () => {
sandbox.stub(fs, 'readFile').resolves(JSON.stringify(DEFAULT_TS_CONFIG))
sandbox.stub(util, 'safeReadFile').resolves(JSON.stringify(DEFAULT_TS_CONFIG))
settings.tsnodeEnabled = false
const result = await configTsNode.tsPath(root, jsCompiled)
expect(result).to.equal(join(root, jsCompiled))
Expand Down

0 comments on commit 0b15536

Please sign in to comment.