Skip to content

Commit

Permalink
feat: Add support for ts 5.7+ (closes #174)
Browse files Browse the repository at this point in the history
  • Loading branch information
nonara committed Dec 4, 2024
1 parent 1bd211d commit 396766c
Show file tree
Hide file tree
Showing 11 changed files with 441 additions and 348 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
"ts-node": "^10.9.1",
"ts-patch": "^3.2.1",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.5.2",
"typescript": "5.5.2",
"ts-next": "npm:typescript@beta",
"ts-expose-internals": "npm:[email protected]"
},
Expand Down
6 changes: 3 additions & 3 deletions projects/core/src/actions/patch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export function patch(moduleNameOrNames: string | string[], opts?: Partial<Insta
const { 1: moduleFile } = entry;
const tsModule = getTsModule(tsPackage, moduleFile, { skipCache: true });

const { moduleName, modulePath } = tsModule;
const { moduleName, modulePath, moduleContentFilePath } = tsModule;
log(
[ '~', `Patching ${chalk.blueBright(moduleName)} in ${chalk.blueBright(path.dirname(modulePath ))}` ],
LogLevel.verbose
Expand All @@ -68,12 +68,12 @@ export function patch(moduleNameOrNames: string | string[], opts?: Partial<Insta
[
'~',
`Writing patched ${chalk.blueBright(moduleName)} to ` +
`${chalk.blueBright(modulePath)}${loadedFromCache ? ' (cached)' : ''}`
`${chalk.blueBright(moduleContentFilePath)}${loadedFromCache ? ' (cached)' : ''}`
],
LogLevel.verbose
);

writeFileWithLock(tsModule.modulePath, js!);
writeFileWithLock(moduleContentFilePath, js!);
if (dts) writeFileWithLock(tsModule.dtsPath!, dts!);

log([ '+', chalk.green(`Successfully patched ${chalk.bold.yellow(moduleName)}.\r\n`) ], LogLevel.verbose);
Expand Down
9 changes: 8 additions & 1 deletion projects/core/src/actions/unpatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,14 @@ export function unpatch(moduleNameOrNames: string | string[], opts?: Partial<Ins
throw new Error(`Cannot find backup file: ${backupPath}. Try reinstalling typescript.`);

const moduleDir = path.dirname(tsModule.modulePath);
const destPath = path.join(moduleDir, path.basename(backupPath));

/* Determine destination path (Need to use moduleContentPath if we're working with a cached module file */
const baseFileName = path.basename(backupPath);
const destPathName = baseFileName === tsModule.moduleName
? path.basename(tsModule.moduleContentFilePath)
: baseFileName;

const destPath = path.join(moduleDir, destPathName);

copyFileWithLock(backupPath, destPath);
}
Expand Down
12 changes: 9 additions & 3 deletions projects/core/src/module/module-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import fs from 'fs';
import { PatchDetail } from '../patch/patch-detail';
import path from 'path';
import { getHash, withFileLock } from '../utils';
import { TsModule } from './ts-module';


/* ****************************************************************************************************************** */
Expand All @@ -22,6 +23,7 @@ export interface ModuleFile {
moduleName: string
patchDetail?: PatchDetail
filePath: string
contentFilePath: string
get content(): string

getHash(): string
Expand Down Expand Up @@ -99,17 +101,21 @@ function readFile(filePath: string, headersOnly?: boolean) {
/* ****************************************************************************************************************** */

export function getModuleFile(filePath: string, loadFullContent?: boolean): ModuleFile {
let { headerLines, content } = readFile(filePath, !loadFullContent);
/* Determine shim redirect file - see: https://github.com/nonara/ts-patch/issues/174 */
const moduleName = path.basename(filePath);
const contentFilePath = TsModule.getContentFilePathForModulePath(filePath);

/* Get PatchDetail */
let { headerLines, content } = readFile(contentFilePath, !loadFullContent);
const patchDetail = PatchDetail.fromHeader(headerLines);

return {
moduleName: path.basename(filePath),
moduleName,
filePath,
contentFilePath,
patchDetail,
get content() {
if (content == null) content = readFile(this.filePath, false).content;
if (content == null) content = readFile(this.contentFilePath, false).content;
return content!;
},
getHash(): string {
Expand Down
27 changes: 26 additions & 1 deletion projects/core/src/module/ts-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,30 @@ import { cachedFilePatchedPrefix } from '../config';
/* ****************************************************************************************************************** */

export namespace TsModule {
export const names = <const>['tsc.js', 'tsserverlibrary.js', 'typescript.js', 'tsserver.js'];
export const names = <const>[ 'tsc.js', 'tsserverlibrary.js', 'typescript.js', 'tsserver.js' ];

export const contentFileMap: Record<string, string> = {
'tsc.js': '_tsc.js',
'tsserver.js': '_tsserver.js'
} satisfies Partial<Record<typeof names[number], string>>;

export function getContentFileName(moduleName: typeof names[number]): string {
return contentFileMap[moduleName] || moduleName;
}

/* Determine shim redirect file - see: https://github.com/nonara/ts-patch/issues/174 */
export function getContentFilePathForModulePath(modulePath: string): string {
const baseName = path.basename(modulePath);
if (!names.includes(baseName as any)) throw new TspError(`Invalid module path: ${modulePath}`);

const redirectFile = contentFileMap[baseName];
const maybeModuleContentPath = redirectFile && path.join(path.dirname(modulePath), redirectFile);
const moduleContentPath = maybeModuleContentPath && fs.existsSync(maybeModuleContentPath)
? maybeModuleContentPath
: modulePath;

return moduleContentPath;
}
}

// endregion
Expand All @@ -30,6 +53,7 @@ export interface TsModule {

moduleName: TsModule.Name;
modulePath: string;
moduleContentFilePath: string;
moduleFile: ModuleFile;
dtsPath: string | undefined;

Expand Down Expand Up @@ -113,6 +137,7 @@ export function getTsModule(
moduleName,
modulePath,
moduleFile,
moduleContentFilePath: moduleFile.contentFilePath,
dtsPath,

cacheKey,
Expand Down
2 changes: 1 addition & 1 deletion projects/core/src/patch/get-patched-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function getPatchedSource(tsModule: TsModule, options?: GetPatchedSourceO
/* Write backup if not patched */
if (!tsModule.isPatched) {
for (const [ key, backupPath ] of Object.entries(backupCachePaths)) {
const srcPath = key === 'dts' ? tsModule.dtsPath : tsModule.modulePath;
const srcPath = key === 'dts' ? tsModule.dtsPath : tsModule.moduleContentFilePath;
if (key === 'dts' && options?.skipDts) continue;
if (!srcPath) continue;

Expand Down
3 changes: 2 additions & 1 deletion test/assets/projects/transform/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"main": "src/index.ts",
"dependencies": {
"esm": "^3.2.25",
"ts-node" : "^10.9.1"
"ts-node" : "^10.9.1",
"semver" : "^7.6.3"
}
}
27 changes: 20 additions & 7 deletions test/assets/projects/transform/run-transform.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const path = require('path');
const semver = require('semver');


/* ****************************************************************************************************************** *
Expand All @@ -9,24 +10,36 @@ function getTransformedFile(transformerKind) {
process.env.TSP_SKIP_CACHE = true;
const tsInstance = require('ts-patch/compiler');

console.log('TS version: ', tsInstance.version);
console.log(`'TS version: ${tsInstance.version}\nNode Version: ${process.version.slice(1)}`);

const configPath = path.join(__dirname, `tsconfig.${transformerKind}.json`);
const configText = tsInstance.sys.readFile(configPath);
const configParseResult = tsInstance.parseConfigFileTextToJson(configPath, configText);
const config = configParseResult.config;

config.compilerOptions.noEmit = false;
config.compilerOptions.skipLibCheck = true;
config.compilerOptions.outDir = 'dist';
/* Parse config */
let compilerOptions;
if (semver.lt(tsInstance.version, '5.5.0', { includePrerelease: false })) {
const configParseResult = tsInstance.parseConfigFileTextToJson(configPath, configText);
compilerOptions = configParseResult.config.compilerOptions;
} else {
const configSourceFile = tsInstance.createSourceFile(configPath, configText, tsInstance.ScriptTarget.Latest);
const configParseResult = tsInstance.parseJsonSourceFileConfigFileContent(configSourceFile, tsInstance.sys, path.dirname(configPath), undefined, configPath);
compilerOptions = configParseResult.options;
}

/* Overwrite options */
Object.assign(compilerOptions, {
noEmit: false,
skipLibCheck: true,
outDir: 'dist',
});

const emittedFiles = new Map();

const writeFile = (fileName, content) => emittedFiles.set(fileName, content);

const program = tsInstance.createProgram({
rootNames: [ path.join(__dirname, 'src', 'index.ts') ],
options: config.compilerOptions,
options: compilerOptions,
});

program.emit(undefined, writeFile);
Expand Down
11 changes: 8 additions & 3 deletions test/tests/actions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import ts from 'typescript';
/* ****************************************************************************************************************** */

const verboseMode = !!process.env.VERBOSE;
// const verboseMode = true;

/* Options to use with install/uninstall */
const testingPackageManagers = [
Expand All @@ -43,7 +44,10 @@ function getModulesSources(tsPackage: TsPackage, moduleNames?: string[]) {
return new Map(moduleNames.map(name => {
const modulePath = tsPackage.getModulePath(name);
const dtsPath = modulePath.replace(/\.js$/, '.d.ts');
const js = fs.readFileSync(modulePath, 'utf-8');

const moduleContentPath = TsModule.getContentFilePathForModulePath(modulePath);

const js = fs.readFileSync(moduleContentPath, 'utf-8');
const dts = fs.existsSync(dtsPath) ? fs.readFileSync(dtsPath, 'utf-8') : undefined;

return [ name, { js, dts } ];
Expand Down Expand Up @@ -192,7 +196,7 @@ describe(`TSP Actions`, () => {
const dtsFilePath = path.join(tsDir, 'typescript.d.ts');

const compilerOptions = Object.assign(ts.getDefaultCompilerOptions(), {
target: 'ES2018',
target: ts.ScriptTarget.ES2018,
lib: [ 'es2018' ],
skipDefaultLibCheck: true
});
Expand Down Expand Up @@ -255,7 +259,8 @@ describe(`TSP Actions`, () => {
expect(src).toBe(origSrcEntry.dts);
}

const src = fs.readFileSync(m.modulePath, 'utf-8');
const contentFilePath = TsModule.getContentFilePathForModulePath(m.modulePath);
const src = fs.readFileSync(contentFilePath, 'utf-8');
expect(src).toBe(origSrcEntry.js);
}
});
Expand Down
8 changes: 6 additions & 2 deletions test/tests/transformer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ describe(`Transformer`, () => {
let loaderResolve: (value?: unknown) => void;
let loaderPromise = new Promise(resolve => loaderResolve = resolve);
beforeAll(() => {
const prepRes = prepareTestProject({ projectName: 'transform', packageManager: 'yarn' });
const prepRes = prepareTestProject({
projectName: 'transform',
packageManager: 'yarn',
tsVersion: '5.5.2',
});
projectPath = prepRes.tmpProjectPath;
loaderResolve();
});
Expand All @@ -35,6 +39,6 @@ describe(`Transformer`, () => {
await loaderPromise;

const res = execSync(`node run-transform.js ${transformerKind}`, { cwd: projectPath });
expect(res.toString('utf8')).toMatch(new RegExp(`^var a = "after-${transformerKind}";?$`, 'm'));
expect(res.toString('utf8')).toMatch(new RegExp(`^(?:var|const) a = "after-${transformerKind}";?$`, 'm'));
});
});
Loading

0 comments on commit 396766c

Please sign in to comment.