Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
787becc4d3 | |||
746ca8767a | |||
55c1a2953a | |||
8e9fcb8135 | |||
18573c777d | |||
fa654b83e3 | |||
aa3c83cd95 | |||
20ed41df42 | |||
7162476f7f | |||
1b012628eb | |||
4081086621 | |||
b9cf09ccba | |||
8463fbc78a | |||
0164eb51a1 | |||
a305dd89dd | |||
fa6b053ee0 | |||
adfba21c67 | |||
050e41cdf9 |
66
changelog.md
66
changelog.md
@@ -1,5 +1,71 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2025-08-29 - 2.6.8 - fix(tsbuild)
|
||||||
|
Avoid process.exit in library, add confirmskiplibcheck flag, improve CLI exit handling and JSON/quiet modes, update test script
|
||||||
|
|
||||||
|
- Changed package.json test script from "tsrun test/test.ts --verbose" to "tstest test/test.ts --verbose".
|
||||||
|
- Library no longer calls process.exit from compile and compileWithErrorTracking; errors are returned or thrown so callers can decide process termination.
|
||||||
|
- skipLibCheck behavior updated: delay/warning only happens when --confirmskiplibcheck is present; otherwise a short informational note is printed (suppressed in --quiet/--json).
|
||||||
|
- CLI now awaits compileGlobStringObject calls and inspects a final error summary attached to argv to decide process.exit(1) when errors occurred.
|
||||||
|
- compileGlobStringObject/exports now respect --quiet and --json modes, emit a JSON summary when --json is used, and attach the final error summary to argv so the CLI can determine exit behavior.
|
||||||
|
|
||||||
|
## 2025-08-18 - 2.6.7 - fix(tspublish)
|
||||||
|
Bump @git.zone/tspublish dependency to ^1.10.3
|
||||||
|
|
||||||
|
- Updated dependency @git.zone/tspublish from ^1.10.2 to ^1.10.3 in package.json
|
||||||
|
|
||||||
|
## 2025-08-18 - 2.6.6 - fix(dependencies)
|
||||||
|
Update dependency @git.zone/tspublish to ^1.10.2
|
||||||
|
|
||||||
|
- Bumped @git.zone/tspublish in package.json from ^1.10.1 to ^1.10.2
|
||||||
|
|
||||||
|
## 2025-08-18 - 2.6.5 - fix(dependencies)
|
||||||
|
Bump dependencies and add pnpm-workspace configuration
|
||||||
|
|
||||||
|
- Updated @git.zone/tspublish from ^1.9.1 to ^1.10.1
|
||||||
|
- Updated @push.rocks/smartfile from ^11.2.4 to ^11.2.7
|
||||||
|
- Updated @push.rocks/smartpath from ^5.0.18 to ^6.0.0
|
||||||
|
- Updated typescript from 5.8.3 to 5.9.2
|
||||||
|
- Updated devDependency @git.zone/tstest from ^1.10.1 to ^2.3.4
|
||||||
|
- Added pnpm-workspace.yaml with onlyBuiltDependencies list (esbuild, mongodb-memory-server, puppeteer)
|
||||||
|
|
||||||
|
## 2025-05-24 - 2.6.4 - fix(dependencies)
|
||||||
|
Add .npmrc and update dependency versions for smartfile and tstest
|
||||||
|
|
||||||
|
- Add .npmrc with registry configuration for npm
|
||||||
|
- Bump @push.rocks/smartfile version from ^11.2.3 to ^11.2.4
|
||||||
|
- Bump @git.zone/tstest version from ^1.9.0 to ^1.10.1
|
||||||
|
|
||||||
|
## 2025-05-21 - 2.6.3 - fix(tsbuild)
|
||||||
|
minor maintenance updates and documentation improvements
|
||||||
|
|
||||||
|
- Updated commit metadata to align with project version
|
||||||
|
- Refined CLI command parsing and diagnostics logging for better clarity
|
||||||
|
- Improved code readability in compiler options merging
|
||||||
|
|
||||||
|
## 2025-05-21 - 2.6.2 - fix(npm configuration)
|
||||||
|
Remove .npmrc file to default npm registry behavior
|
||||||
|
|
||||||
|
- Deleted .npmrc file that hard-coded the npm registry URL to https://registry.npmjs.org/
|
||||||
|
- This change leverages npm's default registry settings and reduces configuration clutter
|
||||||
|
|
||||||
|
## 2025-05-21 - 2.6.1 - fix(tsbuild.classes)
|
||||||
|
Improve error diagnostics handling by removing legacy helper and integrating more robust error summaries in the compilation process
|
||||||
|
|
||||||
|
- Removed the handleDiagnostics method and its legacy usage
|
||||||
|
- Replaced legacy calls with inline processDiagnostics checks for pre-emit and emit phases
|
||||||
|
- Combined error summaries for clearer reporting during emit checks and type validation
|
||||||
|
- Enhanced error output to guide users on resolving TypeScript errors before emission
|
||||||
|
|
||||||
|
## 2025-05-21 - 2.6.0 - feat(tsbuild)
|
||||||
|
Improve task logging and update dependencies
|
||||||
|
|
||||||
|
- Add .npmrc file with npm registry configuration
|
||||||
|
- Update test script to use '--verbose' flag
|
||||||
|
- Bump dependency versions for @push.rocks packages and TypeScript
|
||||||
|
- Enhance TsBuild logging by incorporating task info (e.g. task number, total tasks, output folder, and compile durations)
|
||||||
|
- Propagate task info in compileFileArrayWithErrorTracking for better task tracking
|
||||||
|
|
||||||
## 2025-05-21 - 2.5.2 - fix(tsbuild)
|
## 2025-05-21 - 2.5.2 - fix(tsbuild)
|
||||||
Improve diagnostic error handling and summary reporting for TypeScript compilation by refactoring diagnostic processing and adding pre-emit error checks.
|
Improve diagnostic error handling and summary reporting for TypeScript compilation by refactoring diagnostic processing and adding pre-emit error checks.
|
||||||
|
|
||||||
|
20
package.json
20
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@git.zone/tsbuild",
|
"name": "@git.zone/tsbuild",
|
||||||
"version": "2.5.2",
|
"version": "2.6.8",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "A tool for compiling TypeScript files using the latest nightly features, offering flexible APIs and a CLI for streamlined development.",
|
"description": "A tool for compiling TypeScript files using the latest nightly features, offering flexible APIs and a CLI for streamlined development.",
|
||||||
"main": "dist_ts/index.js",
|
"main": "dist_ts/index.js",
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
"tsbuild": "./cli.js"
|
"tsbuild": "./cli.js"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "tsrun test/test.ts",
|
"test": "tstest test/test.ts --verbose",
|
||||||
"build": "node cli.ts.js --web",
|
"build": "node cli.ts.js --web",
|
||||||
"buildDocs": "tsdoc"
|
"buildDocs": "tsdoc"
|
||||||
},
|
},
|
||||||
@@ -36,20 +36,20 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://code.foss.global/git.zone/tsbuild#README",
|
"homepage": "https://code.foss.global/git.zone/tsbuild#README",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@git.zone/tspublish": "^1.9.1",
|
"@git.zone/tspublish": "^1.10.3",
|
||||||
"@push.rocks/early": "^4.0.4",
|
"@push.rocks/early": "^4.0.4",
|
||||||
"@push.rocks/smartcli": "^4.0.11",
|
"@push.rocks/smartcli": "^4.0.11",
|
||||||
"@push.rocks/smartdelay": "^3.0.5",
|
"@push.rocks/smartdelay": "^3.0.5",
|
||||||
"@push.rocks/smartfile": "^11.1.5",
|
"@push.rocks/smartfile": "^11.2.7",
|
||||||
"@push.rocks/smartlog": "^3.0.7",
|
"@push.rocks/smartlog": "^3.1.8",
|
||||||
"@push.rocks/smartpath": "^5.0.18",
|
"@push.rocks/smartpath": "^6.0.0",
|
||||||
"@push.rocks/smartpromise": "^4.2.2",
|
"@push.rocks/smartpromise": "^4.2.3",
|
||||||
"typescript": "5.7.3"
|
"typescript": "5.9.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@git.zone/tsrun": "^1.2.47",
|
"@git.zone/tsrun": "^1.2.47",
|
||||||
"@push.rocks/tapbundle": "^5.5.6",
|
"@git.zone/tstest": "^2.3.4",
|
||||||
"@types/node": "^22.12.0"
|
"@types/node": "^22.15.21"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"ts/**/*",
|
"ts/**/*",
|
||||||
|
7124
pnpm-lock.yaml
generated
7124
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
4
pnpm-workspace.yaml
Normal file
4
pnpm-workspace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
onlyBuiltDependencies:
|
||||||
|
- esbuild
|
||||||
|
- mongodb-memory-server
|
||||||
|
- puppeteer
|
@@ -1,4 +1,4 @@
|
|||||||
import { tap, expect, expectAsync } from '@push.rocks/tapbundle';
|
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
||||||
|
|
||||||
import * as tsbuild from '../ts/index.js';
|
import * as tsbuild from '../ts/index.js';
|
||||||
|
|
||||||
|
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@git.zone/tsbuild',
|
name: '@git.zone/tsbuild',
|
||||||
version: '2.5.2',
|
version: '2.6.8',
|
||||||
description: 'A tool for compiling TypeScript files using the latest nightly features, offering flexible APIs and a CLI for streamlined development.'
|
description: 'A tool for compiling TypeScript files using the latest nightly features, offering flexible APIs and a CLI for streamlined development.'
|
||||||
}
|
}
|
||||||
|
@@ -41,6 +41,7 @@ export class TsBuild {
|
|||||||
private fileNames: string[] = [];
|
private fileNames: string[] = [];
|
||||||
private options: plugins.typescript.CompilerOptions;
|
private options: plugins.typescript.CompilerOptions;
|
||||||
private argvArg?: any;
|
private argvArg?: any;
|
||||||
|
private taskInfo?: any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new TsBuild instance
|
* Create a new TsBuild instance
|
||||||
@@ -48,10 +49,12 @@ export class TsBuild {
|
|||||||
constructor(
|
constructor(
|
||||||
fileNames: string[] = [],
|
fileNames: string[] = [],
|
||||||
customOptions: CompilerOptions = {},
|
customOptions: CompilerOptions = {},
|
||||||
argvArg?: any
|
argvArg?: any,
|
||||||
|
taskInfo?: any
|
||||||
) {
|
) {
|
||||||
this.fileNames = fileNames;
|
this.fileNames = fileNames;
|
||||||
this.argvArg = argvArg;
|
this.argvArg = argvArg;
|
||||||
|
this.taskInfo = taskInfo;
|
||||||
this.options = this.mergeCompilerOptions(customOptions, argvArg);
|
this.options = this.mergeCompilerOptions(customOptions, argvArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,14 +280,6 @@ export class TsBuild {
|
|||||||
console.log('\n' + '='.repeat(80) + '\n');
|
console.log('\n' + '='.repeat(80) + '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function to handle and log TypeScript diagnostics (legacy method)
|
|
||||||
*/
|
|
||||||
private handleDiagnostics(diagnostics: readonly plugins.typescript.Diagnostic[]): boolean {
|
|
||||||
const errorSummary = this.processDiagnostics(diagnostics);
|
|
||||||
this.displayErrorSummary(errorSummary);
|
|
||||||
return errorSummary.totalErrors > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a TypeScript program from file names and options
|
* Creates a TypeScript program from file names and options
|
||||||
@@ -314,13 +309,30 @@ export class TsBuild {
|
|||||||
*/
|
*/
|
||||||
public async compileWithErrorTracking(): Promise<{ emittedFiles: any[], errorSummary: IErrorSummary }> {
|
public async compileWithErrorTracking(): Promise<{ emittedFiles: any[], errorSummary: IErrorSummary }> {
|
||||||
if (this.options.skipLibCheck) {
|
if (this.options.skipLibCheck) {
|
||||||
console.log('\n⚠️ WARNING ⚠️');
|
if (this.argvArg?.confirmskiplibcheck) {
|
||||||
console.log('You are skipping libcheck... Is that really wanted?');
|
console.log('\n⚠️ WARNING ⚠️');
|
||||||
console.log('Continuing in 5 seconds...\n');
|
console.log('You are skipping libcheck... Is that really wanted?');
|
||||||
await plugins.smartdelay.delayFor(5000);
|
console.log('Continuing in 5 seconds...\n');
|
||||||
|
await plugins.smartdelay.delayFor(5000);
|
||||||
|
} else {
|
||||||
|
// No delay by default; keep a short note unless in quiet/json modes
|
||||||
|
if (!this.argvArg?.quiet && !this.argvArg?.json) {
|
||||||
|
console.log('⚠️ skipLibCheck enabled; use --confirmskiplibcheck to pause with warning.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enhanced logging with task info
|
||||||
|
const startTime = Date.now();
|
||||||
|
if (this.taskInfo) {
|
||||||
|
const { taskNumber, totalTasks, sourcePattern, destDir, fileCount } = this.taskInfo;
|
||||||
|
const relativeDestDir = destDir.replace(process.cwd(), '').replace(/^\//, '');
|
||||||
|
console.log(`\n🔨 [${taskNumber}/${totalTasks}] Compiling ${fileCount} file${fileCount !== 1 ? 's' : ''} from ${sourcePattern}`);
|
||||||
|
console.log(` 📁 Output: ${relativeDestDir}`);
|
||||||
|
} else {
|
||||||
|
console.log(`🔨 Compiling ${this.fileNames.length} files...`);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`🔨 Compiling ${this.fileNames.length} files...`);
|
|
||||||
const done = plugins.smartpromise.defer<{ emittedFiles: any[], errorSummary: IErrorSummary }>();
|
const done = plugins.smartpromise.defer<{ emittedFiles: any[], errorSummary: IErrorSummary }>();
|
||||||
const program = this.createProgram();
|
const program = this.createProgram();
|
||||||
|
|
||||||
@@ -352,7 +364,15 @@ export class TsBuild {
|
|||||||
|
|
||||||
const exitCode = emitResult.emitSkipped ? 1 : 0;
|
const exitCode = emitResult.emitSkipped ? 1 : 0;
|
||||||
if (exitCode === 0) {
|
if (exitCode === 0) {
|
||||||
console.log('\n✅ TypeScript emit succeeded!');
|
const endTime = Date.now();
|
||||||
|
const duration = endTime - startTime;
|
||||||
|
|
||||||
|
if (this.taskInfo) {
|
||||||
|
const { taskNumber, totalTasks } = this.taskInfo;
|
||||||
|
console.log(`✅ [${taskNumber}/${totalTasks}] Task completed in ${duration}ms`);
|
||||||
|
} else {
|
||||||
|
console.log(`✅ TypeScript emit succeeded! (${duration}ms)`);
|
||||||
|
}
|
||||||
|
|
||||||
// Get count of emitted files by type
|
// Get count of emitted files by type
|
||||||
const jsFiles = emitResult.emittedFiles?.filter(f => f.endsWith('.js')).length || 0;
|
const jsFiles = emitResult.emittedFiles?.filter(f => f.endsWith('.js')).length || 0;
|
||||||
@@ -361,7 +381,7 @@ export class TsBuild {
|
|||||||
|
|
||||||
// If we have emitted files, show a summary
|
// If we have emitted files, show a summary
|
||||||
if (emitResult.emittedFiles && emitResult.emittedFiles.length > 0) {
|
if (emitResult.emittedFiles && emitResult.emittedFiles.length > 0) {
|
||||||
console.log(` Generated ${emitResult.emittedFiles.length} files: ${jsFiles} .js, ${dtsFiles} .d.ts, ${mapFiles} source maps`);
|
console.log(` 📄 Generated ${emitResult.emittedFiles.length} files: ${jsFiles} .js, ${dtsFiles} .d.ts, ${mapFiles} source maps`);
|
||||||
}
|
}
|
||||||
|
|
||||||
done.resolve({ emittedFiles: emitResult.emittedFiles || [], errorSummary: combinedErrorSummary });
|
done.resolve({ emittedFiles: emitResult.emittedFiles || [], errorSummary: combinedErrorSummary });
|
||||||
@@ -369,7 +389,9 @@ export class TsBuild {
|
|||||||
this.displayErrorSummary(combinedErrorSummary);
|
this.displayErrorSummary(combinedErrorSummary);
|
||||||
console.error('\n❌ TypeScript emit failed. Please investigate the errors listed above!');
|
console.error('\n❌ TypeScript emit failed. Please investigate the errors listed above!');
|
||||||
console.error(' No output files have been generated.\n');
|
console.error(' No output files have been generated.\n');
|
||||||
process.exit(exitCode);
|
// Do not exit here; return error summary so caller can decide
|
||||||
|
done.resolve({ emittedFiles: [], errorSummary: combinedErrorSummary });
|
||||||
|
return done.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
return done.promise;
|
return done.promise;
|
||||||
@@ -380,10 +402,16 @@ export class TsBuild {
|
|||||||
*/
|
*/
|
||||||
public async compile(): Promise<any[]> {
|
public async compile(): Promise<any[]> {
|
||||||
if (this.options.skipLibCheck) {
|
if (this.options.skipLibCheck) {
|
||||||
console.log('\n⚠️ WARNING ⚠️');
|
if (this.argvArg?.confirmskiplibcheck) {
|
||||||
console.log('You are skipping libcheck... Is that really wanted?');
|
console.log('\n⚠️ WARNING ⚠️');
|
||||||
console.log('Continuing in 5 seconds...\n');
|
console.log('You are skipping libcheck... Is that really wanted?');
|
||||||
await plugins.smartdelay.delayFor(5000);
|
console.log('Continuing in 5 seconds...\n');
|
||||||
|
await plugins.smartdelay.delayFor(5000);
|
||||||
|
} else {
|
||||||
|
if (!this.argvArg?.quiet && !this.argvArg?.json) {
|
||||||
|
console.log('⚠️ skipLibCheck enabled; use --confirmskiplibcheck to pause with warning.');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`🔨 Compiling ${this.fileNames.length} files...`);
|
console.log(`🔨 Compiling ${this.fileNames.length} files...`);
|
||||||
@@ -392,18 +420,20 @@ export class TsBuild {
|
|||||||
|
|
||||||
// Check for pre-emit diagnostics first
|
// Check for pre-emit diagnostics first
|
||||||
const preEmitDiagnostics = plugins.typescript.getPreEmitDiagnostics(program);
|
const preEmitDiagnostics = plugins.typescript.getPreEmitDiagnostics(program);
|
||||||
const hasPreEmitErrors = this.handleDiagnostics(preEmitDiagnostics);
|
const preEmitErrorSummary = this.processDiagnostics(preEmitDiagnostics);
|
||||||
|
|
||||||
// Only continue to emit phase if no pre-emit errors
|
// Only continue to emit phase if no pre-emit errors
|
||||||
if (hasPreEmitErrors) {
|
if (preEmitErrorSummary.totalErrors > 0) {
|
||||||
|
this.displayErrorSummary(preEmitErrorSummary);
|
||||||
console.error('\n❌ TypeScript pre-emit checks failed. Please fix the issues listed above before proceeding.');
|
console.error('\n❌ TypeScript pre-emit checks failed. Please fix the issues listed above before proceeding.');
|
||||||
console.error(' Type errors must be resolved before the compiler can emit output files.\n');
|
console.error(' Type errors must be resolved before the compiler can emit output files.\n');
|
||||||
process.exit(1);
|
// Throw instead of exiting to keep library pure
|
||||||
|
throw new Error('TypeScript pre-emit checks failed.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no pre-emit errors, proceed with emit
|
// If no pre-emit errors, proceed with emit
|
||||||
const emitResult = program.emit();
|
const emitResult = program.emit();
|
||||||
const hasEmitErrors = this.handleDiagnostics(emitResult.diagnostics);
|
const emitErrorSummary = this.processDiagnostics(emitResult.diagnostics);
|
||||||
|
|
||||||
const exitCode = emitResult.emitSkipped ? 1 : 0;
|
const exitCode = emitResult.emitSkipped ? 1 : 0;
|
||||||
if (exitCode === 0) {
|
if (exitCode === 0) {
|
||||||
@@ -421,9 +451,11 @@ export class TsBuild {
|
|||||||
|
|
||||||
done.resolve(emitResult.emittedFiles);
|
done.resolve(emitResult.emittedFiles);
|
||||||
} else {
|
} else {
|
||||||
|
this.displayErrorSummary(emitErrorSummary);
|
||||||
console.error('\n❌ TypeScript emit failed. Please investigate the errors listed above!');
|
console.error('\n❌ TypeScript emit failed. Please investigate the errors listed above!');
|
||||||
console.error(' No output files have been generated.\n');
|
console.error(' No output files have been generated.\n');
|
||||||
process.exit(exitCode);
|
// Throw instead of exiting to keep library pure
|
||||||
|
throw new Error('TypeScript emit failed.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return done.promise;
|
return done.promise;
|
||||||
@@ -444,18 +476,27 @@ export class TsBuild {
|
|||||||
|
|
||||||
// Check for pre-emit diagnostics
|
// Check for pre-emit diagnostics
|
||||||
const preEmitDiagnostics = plugins.typescript.getPreEmitDiagnostics(program);
|
const preEmitDiagnostics = plugins.typescript.getPreEmitDiagnostics(program);
|
||||||
const hasPreEmitErrors = this.handleDiagnostics(preEmitDiagnostics);
|
const preEmitErrorSummary = this.processDiagnostics(preEmitDiagnostics);
|
||||||
|
|
||||||
// Run the emit phase but with noEmit: true to check for emit errors without producing files
|
// Run the emit phase but with noEmit: true to check for emit errors without producing files
|
||||||
const emitResult = program.emit(undefined, undefined, undefined, true);
|
const emitResult = program.emit(undefined, undefined, undefined, true);
|
||||||
const hasEmitErrors = this.handleDiagnostics(emitResult.diagnostics);
|
const emitErrorSummary = this.processDiagnostics(emitResult.diagnostics);
|
||||||
|
|
||||||
const success = !hasPreEmitErrors && !hasEmitErrors && !emitResult.emitSkipped;
|
// Combine error summaries
|
||||||
|
const combinedErrorSummary: IErrorSummary = {
|
||||||
|
errorsByFile: { ...preEmitErrorSummary.errorsByFile, ...emitErrorSummary.errorsByFile },
|
||||||
|
generalErrors: [...preEmitErrorSummary.generalErrors, ...emitErrorSummary.generalErrors],
|
||||||
|
totalErrors: preEmitErrorSummary.totalErrors + emitErrorSummary.totalErrors,
|
||||||
|
totalFiles: Object.keys({ ...preEmitErrorSummary.errorsByFile, ...emitErrorSummary.errorsByFile }).length
|
||||||
|
};
|
||||||
|
|
||||||
|
const success = combinedErrorSummary.totalErrors === 0 && !emitResult.emitSkipped;
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
console.log('\n✅ TypeScript emit check passed! All files can be emitted successfully.');
|
console.log('\n✅ TypeScript emit check passed! All files can be emitted successfully.');
|
||||||
console.log(` ${fileCount} file${fileCount !== 1 ? 's' : ''} ${fileCount !== 1 ? 'are' : 'is'} ready to be compiled.\n`);
|
console.log(` ${fileCount} file${fileCount !== 1 ? 's' : ''} ${fileCount !== 1 ? 'are' : 'is'} ready to be compiled.\n`);
|
||||||
} else {
|
} else {
|
||||||
|
this.displayErrorSummary(combinedErrorSummary);
|
||||||
console.error('\n❌ TypeScript emit check failed. Please fix the issues listed above.');
|
console.error('\n❌ TypeScript emit check failed. Please fix the issues listed above.');
|
||||||
console.error(' The compilation cannot proceed until these errors are resolved.\n');
|
console.error(' The compilation cannot proceed until these errors are resolved.\n');
|
||||||
}
|
}
|
||||||
@@ -478,15 +519,16 @@ export class TsBuild {
|
|||||||
|
|
||||||
// Check for type errors
|
// Check for type errors
|
||||||
const diagnostics = plugins.typescript.getPreEmitDiagnostics(program);
|
const diagnostics = plugins.typescript.getPreEmitDiagnostics(program);
|
||||||
const hasErrors = this.handleDiagnostics(diagnostics);
|
const errorSummary = this.processDiagnostics(diagnostics);
|
||||||
|
|
||||||
// Set success flag
|
// Set success flag
|
||||||
const success = !hasErrors;
|
const success = errorSummary.totalErrors === 0;
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
console.log('\n✅ TypeScript type check passed! No type errors found.');
|
console.log('\n✅ TypeScript type check passed! No type errors found.');
|
||||||
console.log(` All ${fileCount} file${fileCount !== 1 ? 's' : ''} passed type checking successfully.\n`);
|
console.log(` All ${fileCount} file${fileCount !== 1 ? 's' : ''} passed type checking successfully.\n`);
|
||||||
} else {
|
} else {
|
||||||
|
this.displayErrorSummary(errorSummary);
|
||||||
console.error('\n❌ TypeScript type check failed. Please fix the type errors listed above.');
|
console.error('\n❌ TypeScript type check failed. Please fix the type errors listed above.');
|
||||||
console.error(' The type checker found issues that need to be resolved.\n');
|
console.error(' The type checker found issues that need to be resolved.\n');
|
||||||
}
|
}
|
||||||
@@ -540,4 +582,4 @@ export const checkTypes = async (
|
|||||||
): Promise<boolean> => {
|
): Promise<boolean> => {
|
||||||
const tsBuild = new TsBuild(fileNames, options, argvArg);
|
const tsBuild = new TsBuild(fileNames, options, argvArg);
|
||||||
return tsBuild.checkTypes();
|
return tsBuild.checkTypes();
|
||||||
};
|
};
|
||||||
|
@@ -9,7 +9,7 @@ export const runCli = async () => {
|
|||||||
* the standard task compiles anything in ts/ directory to dist directory
|
* the standard task compiles anything in ts/ directory to dist directory
|
||||||
*/
|
*/
|
||||||
tsbuildCli.standardCommand().subscribe(async (argvArg) => {
|
tsbuildCli.standardCommand().subscribe(async (argvArg) => {
|
||||||
tsbuild.compileGlobStringObject(
|
await tsbuild.compileGlobStringObject(
|
||||||
{
|
{
|
||||||
'./ts/**/*.ts': './dist_ts',
|
'./ts/**/*.ts': './dist_ts',
|
||||||
},
|
},
|
||||||
@@ -17,6 +17,10 @@ export const runCli = async () => {
|
|||||||
process.cwd(),
|
process.cwd(),
|
||||||
argvArg
|
argvArg
|
||||||
);
|
);
|
||||||
|
const summary = (argvArg as any)?.__tsbuildFinalErrorSummary;
|
||||||
|
if (summary && summary.totalErrors > 0) {
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,6 +34,10 @@ export const runCli = async () => {
|
|||||||
compilationCommandObject[`./${directory}/**/*.ts`] = `./dist_${directory}`;
|
compilationCommandObject[`./${directory}/**/*.ts`] = `./dist_${directory}`;
|
||||||
}
|
}
|
||||||
await tsbuild.compileGlobStringObject(compilationCommandObject, {}, process.cwd(), argvArg);
|
await tsbuild.compileGlobStringObject(compilationCommandObject, {}, process.cwd(), argvArg);
|
||||||
|
const summary = (argvArg as any)?.__tsbuildFinalErrorSummary;
|
||||||
|
if (summary && summary.totalErrors > 0) {
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -182,6 +190,10 @@ export const runCli = async () => {
|
|||||||
compilationCommandObject[`./${tsFolder}/**/*.ts`] = `./dist_${tsFolder}`;
|
compilationCommandObject[`./${tsFolder}/**/*.ts`] = `./dist_${tsFolder}`;
|
||||||
}
|
}
|
||||||
await tsbuild.compileGlobStringObject(compilationCommandObject, {}, process.cwd(), argvArg);
|
await tsbuild.compileGlobStringObject(compilationCommandObject, {}, process.cwd(), argvArg);
|
||||||
|
const summary = (argvArg as any)?.__tsbuildFinalErrorSummary;
|
||||||
|
if (summary && summary.totalErrors > 0) {
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -6,16 +6,28 @@ export type { CompilerOptions, ScriptTarget, ModuleKind };
|
|||||||
|
|
||||||
export * from './tsbuild.classes.tsbuild.js';
|
export * from './tsbuild.classes.tsbuild.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for task information
|
||||||
|
*/
|
||||||
|
export interface ITaskInfo {
|
||||||
|
taskNumber: number;
|
||||||
|
totalTasks: number;
|
||||||
|
sourcePattern: string;
|
||||||
|
destDir: string;
|
||||||
|
fileCount: number;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* compile an array of absolute file paths with error tracking
|
* compile an array of absolute file paths with error tracking
|
||||||
*/
|
*/
|
||||||
export let compileFileArrayWithErrorTracking = async (
|
export let compileFileArrayWithErrorTracking = async (
|
||||||
fileStringArrayArg: string[],
|
fileStringArrayArg: string[],
|
||||||
compilerOptionsArg: CompilerOptions = {},
|
compilerOptionsArg: CompilerOptions = {},
|
||||||
argvArg?: any
|
argvArg?: any,
|
||||||
|
taskInfo?: ITaskInfo
|
||||||
): Promise<{ emittedFiles: any[], errorSummary: import('./tsbuild.classes.tsbuild.js').IErrorSummary }> => {
|
): Promise<{ emittedFiles: any[], errorSummary: import('./tsbuild.classes.tsbuild.js').IErrorSummary }> => {
|
||||||
const { TsBuild } = await import('./tsbuild.classes.tsbuild.js');
|
const { TsBuild } = await import('./tsbuild.classes.tsbuild.js');
|
||||||
const tsBuild = new TsBuild(fileStringArrayArg, compilerOptionsArg, argvArg);
|
const tsBuild = new TsBuild(fileStringArrayArg, compilerOptionsArg, argvArg, taskInfo);
|
||||||
return tsBuild.compileWithErrorTracking();
|
return tsBuild.compileWithErrorTracking();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -115,12 +127,19 @@ export let compileGlobStringObject = async (
|
|||||||
let compiledFiles: any[] = [];
|
let compiledFiles: any[] = [];
|
||||||
const errorSummaries: import('./tsbuild.classes.tsbuild.js').IErrorSummary[] = [];
|
const errorSummaries: import('./tsbuild.classes.tsbuild.js').IErrorSummary[] = [];
|
||||||
|
|
||||||
// Log the compilation tasks in a nice format
|
const totalTasks = Object.keys(globStringObjectArg).length;
|
||||||
console.log('\n👷 TypeScript Compilation Tasks:');
|
let currentTask = 0;
|
||||||
Object.entries(globStringObjectArg).forEach(([source, dest]) => {
|
|
||||||
console.log(` 📂 ${source} → ${dest}`);
|
// Log the compilation tasks in a nice format (skip for --quiet or --json)
|
||||||
});
|
const isQuiet = argvArg?.quiet === true;
|
||||||
console.log('');
|
const isJson = argvArg?.json === true;
|
||||||
|
if (!isQuiet && !isJson) {
|
||||||
|
console.log(`\n👷 TypeScript Compilation Tasks (${totalTasks} task${totalTasks !== 1 ? 's' : ''}):`);
|
||||||
|
Object.entries(globStringObjectArg).forEach(([source, dest]) => {
|
||||||
|
console.log(` 📂 ${source} → ${dest}`);
|
||||||
|
});
|
||||||
|
console.log('');
|
||||||
|
}
|
||||||
|
|
||||||
for (const keyArg in globStringObjectArg) {
|
for (const keyArg in globStringObjectArg) {
|
||||||
// Type safety check for key
|
// Type safety check for key
|
||||||
@@ -153,7 +172,16 @@ export let compileGlobStringObject = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Compile with error tracking
|
// Compile with error tracking
|
||||||
const result = await compileFileArrayWithErrorTracking(absoluteFilePathArray, updatedTsOptions, argvArg);
|
currentTask++;
|
||||||
|
const taskInfo = {
|
||||||
|
taskNumber: currentTask,
|
||||||
|
totalTasks,
|
||||||
|
sourcePattern: keyArg,
|
||||||
|
destDir: globStringObjectArg[keyArg],
|
||||||
|
fileCount: absoluteFilePathArray.length
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await compileFileArrayWithErrorTracking(absoluteFilePathArray, updatedTsOptions, argvArg, taskInfo);
|
||||||
compiledFiles = compiledFiles.concat(result.emittedFiles);
|
compiledFiles = compiledFiles.concat(result.emittedFiles);
|
||||||
errorSummaries.push(result.errorSummary);
|
errorSummaries.push(result.errorSummary);
|
||||||
}
|
}
|
||||||
@@ -161,7 +189,35 @@ export let compileGlobStringObject = async (
|
|||||||
|
|
||||||
// Display final error summary after all compilation tasks
|
// Display final error summary after all compilation tasks
|
||||||
const finalErrorSummary = mergeErrorSummaries(errorSummaries);
|
const finalErrorSummary = mergeErrorSummaries(errorSummaries);
|
||||||
displayFinalErrorSummary(finalErrorSummary);
|
|
||||||
|
// Output summary based on mode
|
||||||
|
if (isJson) {
|
||||||
|
const result = {
|
||||||
|
success: finalErrorSummary.totalErrors === 0,
|
||||||
|
totals: {
|
||||||
|
errors: finalErrorSummary.totalErrors,
|
||||||
|
filesWithErrors: finalErrorSummary.totalFiles,
|
||||||
|
tasks: totalTasks,
|
||||||
|
},
|
||||||
|
errorsByFile: Object.fromEntries(
|
||||||
|
Object.entries(finalErrorSummary.errorsByFile).map(([file, diags]) => [
|
||||||
|
file,
|
||||||
|
diags.map(d => ({
|
||||||
|
code: d.code,
|
||||||
|
message: plugins.typescript.flattenDiagnosticMessageText(d.messageText as any, '\n'),
|
||||||
|
}))
|
||||||
|
])
|
||||||
|
),
|
||||||
|
};
|
||||||
|
console.log(JSON.stringify(result));
|
||||||
|
} else if (!isQuiet) {
|
||||||
|
displayFinalErrorSummary(finalErrorSummary);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach summary to argvArg so CLI can decide exit behavior
|
||||||
|
if (argvArg && typeof argvArg === 'object') {
|
||||||
|
(argvArg as any).__tsbuildFinalErrorSummary = finalErrorSummary;
|
||||||
|
}
|
||||||
|
|
||||||
return compiledFiles;
|
return compiledFiles;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user