Skip to content

Commit

Permalink
fix: Relative transform paths do not resolve from project root dir wi…
Browse files Browse the repository at this point in the history
…th compiler API (fixes #59)
  • Loading branch information
nonara committed Aug 23, 2021
1 parent 1babac9 commit e38655a
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 25 deletions.
45 changes: 21 additions & 24 deletions src/patch/lib/createProgram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,30 @@ declare const isTSC: boolean;
// region: Helpers
/* ****************************************************************************************************************** */

function getConfig(
compilerOptions: TS.CompilerOptions, rootFileNames: ReadonlyArray<string>, defaultDir: string
)
{
if (compilerOptions.configFilePath === undefined) {
const dir = (rootFileNames.length > 0) ? dirname(rootFileNames[0]) : defaultDir;

const tsconfigPath = ts.findConfigFile(dir, ts.sys.fileExists);
if (tsconfigPath) {
const projectDir = dirname(tsconfigPath);

const config = readConfig(tsconfigPath, dirname(tsconfigPath));
compilerOptions = { ...config.options, ...compilerOptions };
function getProjectDir(compilerOptions: TS.CompilerOptions) {
return compilerOptions.configFilePath && dirname(compilerOptions.configFilePath);
}

function getProjectConfig(compilerOptions: TS.CompilerOptions, rootFileNames: ReadonlyArray<string>) {
let configFilePath = compilerOptions.configFilePath;
let projectDir = getProjectDir(compilerOptions);

if (configFilePath === undefined) {
const baseDir = (rootFileNames.length > 0) ? dirname(rootFileNames[0]) : projectDir ?? process.cwd;
configFilePath = ts.findConfigFile(baseDir, ts.sys.fileExists);

return ({ projectDir, compilerOptions });
if (configFilePath) {
const config = readConfig(configFilePath);
compilerOptions = { ...config.options, ...compilerOptions };
projectDir = getProjectDir(compilerOptions);
}
}

return ({ projectDir: dirname(compilerOptions.configFilePath as string), compilerOptions });
return ({ projectDir, compilerOptions });
}

function readConfig(configFileNamePath: string, projectDir: string) {
function readConfig(configFileNamePath: string) {
const projectDir = dirname(configFileNamePath);
const result = ts.readConfigFile(configFileNamePath, ts.sys.readFile);

if (result.error) throw new Error('Error in tsconfig.json: ' + result.error.messageText);
Expand Down Expand Up @@ -88,8 +90,6 @@ export function createProgram(
configFileParsingDiagnostics?: ReadonlyArray<TS.Diagnostic>
): TS.Program {
let rootNames;
// TODO - Replace all process.cwd with attempting to first resolve from tsConfigFile dir & bump major version
let projectDir = process.cwd();

/* Determine options */
const createOpts = !Array.isArray(rootNamesOrOptions) ? <TS.CreateProgramOptions>rootNamesOrOptions : void 0;
Expand All @@ -105,13 +105,10 @@ export function createProgram(
}

/* Get Config */
const projectConfig = getProjectConfig(options, rootNames);
if (isTSC) {
const info = getConfig(options, rootNames, projectDir);
options = info.compilerOptions;

options = projectConfig.compilerOptions;
if (createOpts) createOpts.options = options;

projectDir = info.projectDir;
}

/* Invoke TS createProgram */
Expand All @@ -122,7 +119,7 @@ export function createProgram(

/* Prepare Plugins */
const plugins = preparePluginsFromCompilerOptions(options.plugins);
const pluginCreator = new PluginCreator(plugins, projectDir);
const pluginCreator = new PluginCreator(plugins, projectConfig.projectDir ?? process.cwd());

/* Prevent recursion in Program transformers */
const programTransformers = new Map(pluginCreator.getProgramTransformers());
Expand Down
2 changes: 2 additions & 0 deletions src/patch/lib/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { PluginCreator } from './plugin';
import { diagnosticMap } from './shared';
import * as TS from 'typescript';
import * as TSPlus from './type-declarations';
// noinspection ES6UnusedImports
import {} from 'ts-expose-internals';


/* ****************************************************************************************************************** *
Expand Down
33 changes: 32 additions & 1 deletion test/patch/typescript.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ const latestVersion =
'utf8'
)).version;

const safelyCode = fs.readFileSync(path.join(testAssetsDir, 'src-files/safely-code.ts')).toString();
const safelyCodePath = path.join(testAssetsDir, 'src-files/safely-code.ts');
const safelyCode = fs.readFileSync(safelyCodePath).toString();
const safelyExpected =
/^var a = { b: 1 };*[\s\r\n]*function abc\(\) {[\s\r\n]*var c = a && a.b;*[\s\r\n]*}[\s\r\n]*console.log\(abc.toString\(\)\);*$/m;

Expand Down Expand Up @@ -98,6 +99,36 @@ describe.each([ ...tsInstallationDirs.keys() ].map(k => k === 'latest' ? latestV
expect(res.outputText).toMatch(safelyExpected);
});

// see: https://github.com/nonara/ts-patch/issues/59
describe(`Relative transformer resolution`, () => {
it('Without project: Resolves from cwd', () => {
const res = ts.transpileModule(safelyCode, {
compilerOptions: {
plugins: [ {
transform: './test/assets/transformers/safely.ts',
} ] as any,
},
});

expect(res.outputText).toMatch(safelyExpected);
});

it('With project: Resolves from project root', () => {
const compilerOptions = {
skipLibCheck: true,
skipDefaultLibCheck: true,
plugins: [ {
transform: '../transformers/safely.ts',
} ] as any
};
const program = ts.createProgram([ safelyCodePath ], compilerOptions);
let outputText: string;
program.emit(void 0, (_, src) => outputText = src);
expect(outputText!).toMatch(safelyExpected);
});

});

it('Merges transformers', () => {
const customTransformer = jest.fn((sf: any) => sf);

Expand Down

0 comments on commit e38655a

Please sign in to comment.