Skip to content

Commit

Permalink
fix: Edge cases exist which causes ts-node to fail with register scri…
Browse files Browse the repository at this point in the history
…pt (fixes #162)
  • Loading branch information
nonara committed Oct 21, 2022
1 parent 1ab99cd commit 09f79e2
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 20 deletions.
41 changes: 27 additions & 14 deletions src/transformer.ts
@@ -1,6 +1,6 @@
import path from "path";
import ts, { CompilerOptions } from "typescript";
import { RunMode, TsTransformPathsConfig, TsTransformPathsContext, VisitorContext } from "./types";
import { RunMode, TsNodeState, TsTransformPathsConfig, TsTransformPathsContext, VisitorContext } from "./types";
import { nodeVisitor } from "./visitor";
import { createHarmonyFactory } from "./harmony";
import { Minimatch } from "minimatch";
Expand All @@ -16,6 +16,7 @@ function getTsProperties(args: Parameters<typeof transformer>) {
let fileNames: readonly string[] | undefined;
let compilerOptions: CompilerOptions;
let runMode: RunMode;
let tsNodeState: TsNodeState | undefined;

const { 0: program, 2: extras, 3: manualTransformOptions } = args;

Expand All @@ -25,13 +26,11 @@ function getTsProperties(args: Parameters<typeof transformer>) {

/* Determine RunMode & Setup */
// Note: ts-node passes a Program with the paths property stripped, so we do some comparison to determine if it's the caller
const maybeIsTsNode =
tsNodeProps &&
(!program ||
(compilerOptions!.configFilePath === tsNodeProps.compilerOptions.configFilePath && !compilerOptions!.paths));
const isTsNode =
tsNodeProps && (!program || compilerOptions!.configFilePath === tsNodeProps.compilerOptions.configFilePath);

// RunMode: Program
if (program && !maybeIsTsNode) {
if (program && !isTsNode) {
runMode = RunMode.Program;
compilerOptions = compilerOptions!;
}
Expand All @@ -42,18 +41,32 @@ function getTsProperties(args: Parameters<typeof transformer>) {
compilerOptions = manualTransformOptions.compilerOptions!;
}
// RunMode: TsNode
else if (maybeIsTsNode) {
runMode = RunMode.TsNode;
else if (isTsNode) {
fileNames = tsNodeProps.fileNames;
compilerOptions = tsNodeProps.compilerOptions;
runMode = RunMode.TsNode;

tsNodeState =
!program ||
(fileNames.length > 1 && program?.getRootFileNames().length === 1) ||
(!compilerOptions!.paths && tsNodeProps!.compilerOptions.paths)
? TsNodeState.Stripped
: TsNodeState.Full;

compilerOptions =
tsNodeState === TsNodeState.Full
? compilerOptions!
: {
...(program?.getCompilerOptions() ?? {}),
...tsNodeProps!.compilerOptions,
};
} else {
throw new Error(
`Cannot transform without a Program, ts-node instance, or manual parameters supplied. ` +
`Make sure you're using ts-patch or ts-node with transpileOnly.`
);
}

return { tsInstance, compilerOptions, fileNames, runMode };
return { tsInstance, compilerOptions, fileNames, runMode, tsNodeState };
}

// endregion
Expand All @@ -80,7 +93,8 @@ export default function transformer(
tsInstance,
compilerOptions,
fileNames,
runMode
runMode,
tsNodeState
} = getTsProperties([ program, pluginConfig, transformerExtras, manualTransformOptions ]);

const rootDirs = compilerOptions.rootDirs?.filter(path.isAbsolute);
Expand All @@ -89,14 +103,12 @@ export default function transformer(

/* Add supplements for various run modes */
let emitHost = transformationContext.getEmitHost();
if (!emitHost) {
if (!emitHost || tsNodeState === TsNodeState.Stripped) {
if (!fileNames)
throw new Error(
`No EmitHost found and could not determine files to be processed. Please file an issue with a reproduction!`
);
emitHost = createSyntheticEmitHost(compilerOptions, tsInstance, getCanonicalFileName, fileNames as string[]);
} else if (runMode === RunMode.TsNode) {
Object.assign(emitHost, { getCompilerOptions: () => compilerOptions });
}

/* Create Visitor Context */
Expand All @@ -117,6 +129,7 @@ export default function transformer(
tsVersionMinor,
emitHost,
runMode,
tsNodeState,
excludeMatchers: config.exclude?.map((globPattern) => new Minimatch(globPattern, { matchBase: true })),
outputFileNamesCache: new Map(),
// Get paths patterns appropriate for TS compiler version
Expand Down
6 changes: 6 additions & 0 deletions src/types.ts
Expand Up @@ -36,6 +36,7 @@ export interface TsTransformPathsContext {
readonly tsVersionMinor: number;
readonly tsFactory?: ts.NodeFactory;
readonly runMode: RunMode;
readonly tsNodeState?: TsNodeState;
readonly program?: ts.Program;
readonly config: TsTransformPathsConfig;
readonly compilerOptions: CompilerOptions;
Expand Down Expand Up @@ -68,4 +69,9 @@ export enum RunMode {
Program = "program",
}

export enum TsNodeState {
Full,
Stripped,
}

// endregion
2 changes: 1 addition & 1 deletion src/utils/ts-helpers.ts
Expand Up @@ -100,7 +100,7 @@ export function getTsNodeRegistrationProperties(tsInstance: typeof ts) {
const fileNames = pcl?.fileNames || config.fileNames;
const compilerOptions = Object.assign(config.options, options.compilerOptions, { outDir: pcl?.options.outDir });

return { compilerOptions, fileNames };
return { compilerOptions, fileNames, tsNodeOptions: options };
}

// endregion
2 changes: 1 addition & 1 deletion test/projects/extras/tsconfig.json
Expand Up @@ -2,12 +2,12 @@
"include": [ "src" ],

"ts-node": {
"transpileOnly": true,
"require": [ "typescript-transform-paths/register" ]
},

"compilerOptions": {
"noEmit": true,
"outDir": "dist",

"rootDir": ".",
"module": "CommonJS",
Expand Down
15 changes: 11 additions & 4 deletions test/tests/extras.test.ts
Expand Up @@ -33,9 +33,16 @@ describe(`Extra Tests`, () => {
}
});

test(`Register script transforms with ts-node`, () => {
const res = execSync("npx ts-node src/index.ts", { cwd: projectRoot }).toString();
expect(res).toMatch(/^null($|\r?\n)/);
});
describe(`ts-node register script`, () => {
test(`Works with --transpileOnly`, () => {
const res = execSync("npx ts-node --transpileOnly src/index.ts", { cwd: projectRoot }).toString();
expect(res).toMatch(/^null($|\r?\n)/);
});

test(`Works with --typeCheck`, () => {
const res = execSync("npx ts-node --typeCheck src/index.ts", { cwd: projectRoot }).toString();
expect(res).toMatch(/^null($|\r?\n)/);
});
})
});
});

0 comments on commit 09f79e2

Please sign in to comment.