11#! /usr/bin/env node
22"use strict" ;
33
4+ const { spawnSync } = require ( "child_process" ) ;
45const fs = require ( "fs" ) ;
56const os = require ( "os" ) ;
67const path = require ( "path" ) ;
7- const ts = require ( "typescript" ) ;
88const { beforeEachTestCase } = require ( "./helpers/common" ) ;
99
10+ // TypeScript 7 dropped the JS compiler API (require("typescript") only exposes the version),
11+ // so type-checking goes through the tsc CLI, which behaves the same on v5 and v7.
12+ // Its exports map hides ./bin/tsc, hence resolving through package.json (which is exported).
13+ const tsPackageJsonPath = require . resolve ( "typescript/package.json" ) ;
14+ const tscBin = path . join ( path . dirname ( tsPackageJsonPath ) , require ( tsPackageJsonPath ) . bin . tsc ) ;
15+
1016// This test ensures the published TypeScript declarations remain valid for a consumer project.
1117describe ( "TypeScript usage" , ( ) => {
1218 beforeEach ( beforeEachTestCase ) ;
@@ -15,21 +21,24 @@ describe("TypeScript usage", () => {
1521 const tempDir = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , "java-caller-ts-" ) ) ;
1622 const sourcePath = path . join ( tempDir , "example.ts" ) ;
1723
24+ // Paths are absolute: the tsconfig lives outside the project, so nothing resolves relatively.
1825 const config = {
1926 compilerOptions : {
2027 target : "ES2019" ,
21- module : "CommonJS" ,
22- moduleResolution : "Node" ,
28+ // node16 rather than CommonJS/Node: TypeScript 7 removed the node10 resolver
29+ module : "node16" ,
30+ moduleResolution : "node16" ,
2331 strict : true ,
32+ noEmit : true ,
2433 esModuleInterop : true ,
2534 allowSyntheticDefaultImports : true ,
26- baseUrl : process . cwd ( ) ,
2735 paths : {
28- "java-caller" : [ "lib/index.d.ts" ]
36+ "java-caller" : [ path . join ( process . cwd ( ) , "lib/index.d.ts" ) ]
2937 } ,
38+ typeRoots : [ path . join ( process . cwd ( ) , "node_modules/@types" ) ] ,
3039 types : [ "node" ]
3140 } ,
32- include : [ "example.ts" ]
41+ include : [ sourcePath ]
3342 } ;
3443
3544 fs . writeFileSync ( sourcePath , `import { JavaCaller, JavaCallerOptions, JavaCallerResult } from "java-caller";
@@ -59,23 +68,16 @@ async function run(): Promise<void> {
5968run();
6069` ) ;
6170
71+ const configPath = path . join ( tempDir , "tsconfig.json" ) ;
72+ fs . writeFileSync ( configPath , JSON . stringify ( config , null , 4 ) ) ;
73+
6274 try {
63- const parsed = ts . parseJsonConfigFileContent ( config , ts . sys , tempDir ) ;
64- const program = ts . createProgram ( { rootNames : parsed . fileNames , options : parsed . options } ) ;
65- const diagnostics = ts . getPreEmitDiagnostics ( program ) ;
75+ const res = spawnSync ( process . execPath , [ tscBin , "--project" , configPath , "--pretty" , "false" ] , {
76+ encoding : "utf8"
77+ } ) ;
6678
67- if ( diagnostics . length ) {
68- const formatted = diagnostics
69- . map ( diag => {
70- if ( diag . file && typeof diag . start === "number" ) {
71- const { line, character } = diag . file . getLineAndCharacterOfPosition ( diag . start ) ;
72- const message = ts . flattenDiagnosticMessageText ( diag . messageText , "\n" ) ;
73- return `${ diag . file . fileName } (${ line + 1 } ,${ character + 1 } ): ${ message } ` ;
74- }
75- return ts . flattenDiagnosticMessageText ( diag . messageText , "\n" ) ;
76- } )
77- . join ( "\n" ) ;
78- throw new Error ( `TypeScript compilation failed:\n${ formatted } ` ) ;
79+ if ( res . status !== 0 ) {
80+ throw new Error ( `TypeScript compilation failed:\n${ res . stdout || "" } ${ res . stderr || "" } ` ) ;
7981 }
8082 } finally {
8183 fs . rmSync ( tempDir , { recursive : true , force : true } ) ;
0 commit comments