Compare commits
	
		
			2 Commits
		
	
	
		
			v2.3.0
			...
			5ecf4b7125
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 5ecf4b7125 | |||
| 2aa6348cdd | 
@@ -1,5 +1,12 @@
 | 
				
			|||||||
# Changelog
 | 
					# Changelog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 2025-03-20 - 2.3.1 - fix(compiler)
 | 
				
			||||||
 | 
					Refactor compiler implementation with consolidated TsBuild class and improved diagnostics handling
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Removed legacy tsbuild.classes.compiler.ts and introduced tsbuild.classes.tsbuild.ts
 | 
				
			||||||
 | 
					- Unified compiler options merging, reading tsconfig.json, and diagnostics reporting within the TsBuild class
 | 
				
			||||||
 | 
					- Updated exports to reference the new compiler class implementation for backward compatibility
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 2025-03-20 - 2.3.0 - feat(cli)
 | 
					## 2025-03-20 - 2.3.0 - feat(cli)
 | 
				
			||||||
Add emitcheck command to validate TS file emission without generating output
 | 
					Add emitcheck command to validate TS file emission without generating output
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "@git.zone/tsbuild",
 | 
					  "name": "@git.zone/tsbuild",
 | 
				
			||||||
  "version": "2.3.0",
 | 
					  "version": "2.3.1",
 | 
				
			||||||
  "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",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,6 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
export const commitinfo = {
 | 
					export const commitinfo = {
 | 
				
			||||||
  name: '@git.zone/tsbuild',
 | 
					  name: '@git.zone/tsbuild',
 | 
				
			||||||
  version: '2.3.0',
 | 
					  version: '2.3.1',
 | 
				
			||||||
  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.'
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,215 +0,0 @@
 | 
				
			|||||||
// import all the stuff we need
 | 
					 | 
				
			||||||
import * as plugins from './plugins.js';
 | 
					 | 
				
			||||||
import * as paths from './paths.js';
 | 
					 | 
				
			||||||
import type { CompilerOptions, ScriptTarget, ModuleKind } from './tsbuild.exports.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * the default typescript compilerOptions
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export const compilerOptionsDefault: CompilerOptions = {
 | 
					 | 
				
			||||||
  declaration: true,
 | 
					 | 
				
			||||||
  emitDecoratorMetadata: true,
 | 
					 | 
				
			||||||
  experimentalDecorators: true,
 | 
					 | 
				
			||||||
  inlineSourceMap: true,
 | 
					 | 
				
			||||||
  noEmitOnError: true,
 | 
					 | 
				
			||||||
  outDir: 'dist_ts/',
 | 
					 | 
				
			||||||
  module: plugins.typescript.ModuleKind.NodeNext,
 | 
					 | 
				
			||||||
  target: plugins.typescript.ScriptTarget.ESNext,
 | 
					 | 
				
			||||||
  moduleResolution: plugins.typescript.ModuleResolutionKind.NodeNext,
 | 
					 | 
				
			||||||
  lib: ['lib.dom.d.ts', 'lib.es2022.d.ts'],
 | 
					 | 
				
			||||||
  noImplicitAny: true,
 | 
					 | 
				
			||||||
  esModuleInterop: true,
 | 
					 | 
				
			||||||
  useDefineForClassFields: false,
 | 
					 | 
				
			||||||
  verbatimModuleSyntax: true,
 | 
					 | 
				
			||||||
  baseUrl: './',
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * merges compilerOptions with the default compiler options
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export const mergeCompilerOptions = (
 | 
					 | 
				
			||||||
  customTsOptions: CompilerOptions,
 | 
					 | 
				
			||||||
  argvArg?: any
 | 
					 | 
				
			||||||
): CompilerOptions => {
 | 
					 | 
				
			||||||
  // create merged options
 | 
					 | 
				
			||||||
  const mergedOptions: CompilerOptions = {
 | 
					 | 
				
			||||||
    ...compilerOptionsDefault,
 | 
					 | 
				
			||||||
    ...customTsOptions,
 | 
					 | 
				
			||||||
    ...(argvArg && argvArg.skiplibcheck
 | 
					 | 
				
			||||||
      ? {
 | 
					 | 
				
			||||||
          skipLibCheck: true,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      : {}),
 | 
					 | 
				
			||||||
    ...(argvArg && argvArg.allowimplicitany
 | 
					 | 
				
			||||||
      ? {
 | 
					 | 
				
			||||||
          noImplicitAny: false,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      : {}),
 | 
					 | 
				
			||||||
    ...(argvArg && argvArg.commonjs
 | 
					 | 
				
			||||||
      ? {
 | 
					 | 
				
			||||||
          module: plugins.typescript.ModuleKind.CommonJS,
 | 
					 | 
				
			||||||
          moduleResolution: plugins.typescript.ModuleResolutionKind.NodeJs,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      : {}),
 | 
					 | 
				
			||||||
    ...(() => {
 | 
					 | 
				
			||||||
      const returnObject: CompilerOptions = {};
 | 
					 | 
				
			||||||
      console.log(`looking at tsconfig.json at ${paths.cwd}`);
 | 
					 | 
				
			||||||
      const tsconfig = plugins.smartfile.fs.toObjectSync(plugins.path.join(paths.cwd, 'tsconfig.json'));
 | 
					 | 
				
			||||||
      if (tsconfig && tsconfig.compilerOptions && tsconfig.compilerOptions.baseUrl) {
 | 
					 | 
				
			||||||
        console.log('baseUrl found in tsconfig.json');
 | 
					 | 
				
			||||||
        returnObject.baseUrl = tsconfig.compilerOptions.baseUrl;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (tsconfig && tsconfig.compilerOptions && tsconfig.compilerOptions.paths) {
 | 
					 | 
				
			||||||
        console.log('paths found in tsconfig.json');
 | 
					 | 
				
			||||||
        returnObject.paths = tsconfig.compilerOptions.paths;
 | 
					 | 
				
			||||||
        for (const path of Object.keys(tsconfig.compilerOptions.paths)) {
 | 
					 | 
				
			||||||
          returnObject.paths[path][0] = returnObject.paths[path][0].replace('./ts_', './dist_ts_');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      return returnObject;
 | 
					 | 
				
			||||||
    })(),
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  console.log(mergedOptions);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return mergedOptions;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * the internal main compiler function that compiles the files
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export const compiler = async (
 | 
					 | 
				
			||||||
  fileNames: string[],
 | 
					 | 
				
			||||||
  options: plugins.typescript.CompilerOptions,
 | 
					 | 
				
			||||||
  argvArg?: any
 | 
					 | 
				
			||||||
): Promise<any[]> => {
 | 
					 | 
				
			||||||
  if (options.skipLibCheck) {
 | 
					 | 
				
			||||||
    console.log('? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?');
 | 
					 | 
				
			||||||
    console.log('You are skipping libcheck... Is that really wanted?');
 | 
					 | 
				
			||||||
    console.log('continuing in 5 seconds...');
 | 
					 | 
				
			||||||
    console.log('? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?');
 | 
					 | 
				
			||||||
    await plugins.smartdelay.delayFor(5000);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  console.log(`Compiling ${fileNames.length} files...`);
 | 
					 | 
				
			||||||
  const done = plugins.smartpromise.defer<any[]>();
 | 
					 | 
				
			||||||
  const program = plugins.typescript.createProgram(fileNames, options);
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  // Check for pre-emit diagnostics first
 | 
					 | 
				
			||||||
  const preEmitDiagnostics = plugins.typescript.getPreEmitDiagnostics(program);
 | 
					 | 
				
			||||||
  let hasErrors = false;
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  // Log pre-emit diagnostics if any
 | 
					 | 
				
			||||||
  if (preEmitDiagnostics.length > 0) {
 | 
					 | 
				
			||||||
    preEmitDiagnostics.forEach((diagnostic) => {
 | 
					 | 
				
			||||||
      hasErrors = true;
 | 
					 | 
				
			||||||
      if (diagnostic.file) {
 | 
					 | 
				
			||||||
        const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!);
 | 
					 | 
				
			||||||
        const message = plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
 | 
					 | 
				
			||||||
        console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        console.log(
 | 
					 | 
				
			||||||
          `${plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}`
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  // Only continue to emit phase if no pre-emit errors
 | 
					 | 
				
			||||||
  if (hasErrors) {
 | 
					 | 
				
			||||||
    console.error('TypeScript pre-emit checks failed. Please fix the issues above.');
 | 
					 | 
				
			||||||
    process.exit(1);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  // If no pre-emit errors, proceed with emit
 | 
					 | 
				
			||||||
  const emitResult = program.emit();
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  // Check for emit diagnostics
 | 
					 | 
				
			||||||
  if (emitResult.diagnostics.length > 0) {
 | 
					 | 
				
			||||||
    emitResult.diagnostics.forEach((diagnostic) => {
 | 
					 | 
				
			||||||
      if (diagnostic.file) {
 | 
					 | 
				
			||||||
        const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!);
 | 
					 | 
				
			||||||
        const message = plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
 | 
					 | 
				
			||||||
        console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        console.log(
 | 
					 | 
				
			||||||
          `${plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}`
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const exitCode = emitResult.emitSkipped ? 1 : 0;
 | 
					 | 
				
			||||||
  if (exitCode === 0) {
 | 
					 | 
				
			||||||
    console.log('TypeScript emit succeeded!');
 | 
					 | 
				
			||||||
    done.resolve(emitResult.emittedFiles);
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    console.error('TypeScript emit failed. Please investigate!');
 | 
					 | 
				
			||||||
    process.exit(exitCode);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return done.promise;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Function to check if a TypeScript file can be emitted without actually emitting it
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export const emitCheck = async (
 | 
					 | 
				
			||||||
  fileNames: string[],
 | 
					 | 
				
			||||||
  options: plugins.typescript.CompilerOptions = {},
 | 
					 | 
				
			||||||
  argvArg?: any
 | 
					 | 
				
			||||||
): Promise<boolean> => {
 | 
					 | 
				
			||||||
  console.log(`Checking if ${fileNames.length} files can be emitted...`);
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  // Create a program
 | 
					 | 
				
			||||||
  const program = plugins.typescript.createProgram(fileNames, {
 | 
					 | 
				
			||||||
    ...options,
 | 
					 | 
				
			||||||
    noEmit: true
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  // Check for pre-emit diagnostics
 | 
					 | 
				
			||||||
  const preEmitDiagnostics = plugins.typescript.getPreEmitDiagnostics(program);
 | 
					 | 
				
			||||||
  let hasErrors = false;
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  // Log pre-emit diagnostics if any
 | 
					 | 
				
			||||||
  if (preEmitDiagnostics.length > 0) {
 | 
					 | 
				
			||||||
    preEmitDiagnostics.forEach((diagnostic) => {
 | 
					 | 
				
			||||||
      hasErrors = true;
 | 
					 | 
				
			||||||
      if (diagnostic.file) {
 | 
					 | 
				
			||||||
        const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!);
 | 
					 | 
				
			||||||
        const message = plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
 | 
					 | 
				
			||||||
        console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        console.log(
 | 
					 | 
				
			||||||
          `${plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}`
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  // Run the emit phase but with noEmit: true to check for emit errors without producing files
 | 
					 | 
				
			||||||
  const emitResult = program.emit(undefined, undefined, undefined, true);
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  // Check for emit diagnostics
 | 
					 | 
				
			||||||
  if (emitResult.diagnostics.length > 0) {
 | 
					 | 
				
			||||||
    emitResult.diagnostics.forEach((diagnostic) => {
 | 
					 | 
				
			||||||
      hasErrors = true;
 | 
					 | 
				
			||||||
      if (diagnostic.file) {
 | 
					 | 
				
			||||||
        const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!);
 | 
					 | 
				
			||||||
        const message = plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
 | 
					 | 
				
			||||||
        console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        console.log(
 | 
					 | 
				
			||||||
          `${plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}`
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  if (!hasErrors && !emitResult.emitSkipped) {
 | 
					 | 
				
			||||||
    console.log('TypeScript emit check passed! File can be emitted successfully.');
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    console.error('TypeScript emit check failed. Please fix the issues above.');
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
							
								
								
									
										271
									
								
								ts/tsbuild.classes.tsbuild.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										271
									
								
								ts/tsbuild.classes.tsbuild.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,271 @@
 | 
				
			|||||||
 | 
					// import all the stuff we need
 | 
				
			||||||
 | 
					import * as plugins from './plugins.js';
 | 
				
			||||||
 | 
					import * as paths from './paths.js';
 | 
				
			||||||
 | 
					import type { CompilerOptions, ScriptTarget, ModuleKind } from './tsbuild.exports.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Default compiler options for TypeScript compilation
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export const compilerOptionsDefault: CompilerOptions = {
 | 
				
			||||||
 | 
					  declaration: true,
 | 
				
			||||||
 | 
					  emitDecoratorMetadata: true,
 | 
				
			||||||
 | 
					  experimentalDecorators: true,
 | 
				
			||||||
 | 
					  inlineSourceMap: true,
 | 
				
			||||||
 | 
					  noEmitOnError: true,
 | 
				
			||||||
 | 
					  outDir: 'dist_ts/',
 | 
				
			||||||
 | 
					  module: plugins.typescript.ModuleKind.NodeNext,
 | 
				
			||||||
 | 
					  target: plugins.typescript.ScriptTarget.ESNext,
 | 
				
			||||||
 | 
					  moduleResolution: plugins.typescript.ModuleResolutionKind.NodeNext,
 | 
				
			||||||
 | 
					  lib: ['lib.dom.d.ts', 'lib.es2022.d.ts'],
 | 
				
			||||||
 | 
					  noImplicitAny: true,
 | 
				
			||||||
 | 
					  esModuleInterop: true,
 | 
				
			||||||
 | 
					  useDefineForClassFields: false,
 | 
				
			||||||
 | 
					  verbatimModuleSyntax: true,
 | 
				
			||||||
 | 
					  baseUrl: './',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * TsBuild class for handling TypeScript compilation
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export class TsBuild {
 | 
				
			||||||
 | 
					  private fileNames: string[] = [];
 | 
				
			||||||
 | 
					  private options: plugins.typescript.CompilerOptions;
 | 
				
			||||||
 | 
					  private argvArg?: any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Create a new TsBuild instance
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  constructor(
 | 
				
			||||||
 | 
					    fileNames: string[] = [], 
 | 
				
			||||||
 | 
					    customOptions: CompilerOptions = {}, 
 | 
				
			||||||
 | 
					    argvArg?: any
 | 
				
			||||||
 | 
					  ) {
 | 
				
			||||||
 | 
					    this.fileNames = fileNames;
 | 
				
			||||||
 | 
					    this.argvArg = argvArg;
 | 
				
			||||||
 | 
					    this.options = this.mergeCompilerOptions(customOptions, argvArg);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Helper function to read and process tsconfig.json
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  private getTsConfigOptions(): CompilerOptions {
 | 
				
			||||||
 | 
					    console.log(`looking at tsconfig.json at ${paths.cwd}`);
 | 
				
			||||||
 | 
					    const tsconfig = plugins.smartfile.fs.toObjectSync(plugins.path.join(paths.cwd, 'tsconfig.json'));
 | 
				
			||||||
 | 
					    const returnObject: CompilerOptions = {};
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (!tsconfig || !tsconfig.compilerOptions) {
 | 
				
			||||||
 | 
					      return returnObject;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (tsconfig.compilerOptions.baseUrl) {
 | 
				
			||||||
 | 
					      console.log('baseUrl found in tsconfig.json');
 | 
				
			||||||
 | 
					      returnObject.baseUrl = tsconfig.compilerOptions.baseUrl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (tsconfig.compilerOptions.paths) {
 | 
				
			||||||
 | 
					      console.log('paths found in tsconfig.json');
 | 
				
			||||||
 | 
					      returnObject.paths = tsconfig.compilerOptions.paths;
 | 
				
			||||||
 | 
					      for (const path of Object.keys(tsconfig.compilerOptions.paths)) {
 | 
				
			||||||
 | 
					        returnObject.paths[path][0] = returnObject.paths[path][0].replace('./ts_', './dist_ts_');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return returnObject;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Process command line arguments and return applicable compiler options
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  private getCommandLineOptions(argvArg?: any): CompilerOptions {
 | 
				
			||||||
 | 
					    if (!argvArg) return {};
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    const options: CompilerOptions = {};
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (argvArg.skiplibcheck) {
 | 
				
			||||||
 | 
					      options.skipLibCheck = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (argvArg.allowimplicitany) {
 | 
				
			||||||
 | 
					      options.noImplicitAny = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (argvArg.commonjs) {
 | 
				
			||||||
 | 
					      options.module = plugins.typescript.ModuleKind.CommonJS;
 | 
				
			||||||
 | 
					      options.moduleResolution = plugins.typescript.ModuleResolutionKind.NodeJs;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return options;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Merges compilerOptions with the default compiler options
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  public mergeCompilerOptions(
 | 
				
			||||||
 | 
					    customTsOptions: CompilerOptions = {},
 | 
				
			||||||
 | 
					    argvArg?: any
 | 
				
			||||||
 | 
					  ): CompilerOptions {
 | 
				
			||||||
 | 
					    // create merged options
 | 
				
			||||||
 | 
					    const mergedOptions: CompilerOptions = {
 | 
				
			||||||
 | 
					      ...compilerOptionsDefault,
 | 
				
			||||||
 | 
					      ...customTsOptions,
 | 
				
			||||||
 | 
					      ...this.getCommandLineOptions(argvArg),
 | 
				
			||||||
 | 
					      ...this.getTsConfigOptions(),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    console.log(mergedOptions);
 | 
				
			||||||
 | 
					    return mergedOptions;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Helper function to handle and log TypeScript diagnostics
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  private handleDiagnostics(diagnostics: readonly plugins.typescript.Diagnostic[]): boolean {
 | 
				
			||||||
 | 
					    let hasErrors = false;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    diagnostics.forEach((diagnostic) => {
 | 
				
			||||||
 | 
					      hasErrors = true;
 | 
				
			||||||
 | 
					      if (diagnostic.file) {
 | 
				
			||||||
 | 
					        const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!);
 | 
				
			||||||
 | 
					        const message = plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
 | 
				
			||||||
 | 
					        console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        console.log(
 | 
				
			||||||
 | 
					          `${plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}`
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return hasErrors;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Creates a TypeScript program from file names and options
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  private createProgram(
 | 
				
			||||||
 | 
					    options: plugins.typescript.CompilerOptions = this.options
 | 
				
			||||||
 | 
					  ): plugins.typescript.Program {
 | 
				
			||||||
 | 
					    return plugins.typescript.createProgram(this.fileNames, options);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Set file names to be compiled
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  public setFileNames(fileNames: string[]): void {
 | 
				
			||||||
 | 
					    this.fileNames = fileNames;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Set compiler options
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  public setOptions(options: CompilerOptions): void {
 | 
				
			||||||
 | 
					    this.options = { ...this.options, ...options };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * The main compiler function that compiles the files
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  public async compile(): Promise<any[]> {
 | 
				
			||||||
 | 
					    if (this.options.skipLibCheck) {
 | 
				
			||||||
 | 
					      console.log('? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?');
 | 
				
			||||||
 | 
					      console.log('You are skipping libcheck... Is that really wanted?');
 | 
				
			||||||
 | 
					      console.log('continuing in 5 seconds...');
 | 
				
			||||||
 | 
					      console.log('? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?');
 | 
				
			||||||
 | 
					      await plugins.smartdelay.delayFor(5000);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    console.log(`Compiling ${this.fileNames.length} files...`);
 | 
				
			||||||
 | 
					    const done = plugins.smartpromise.defer<any[]>();
 | 
				
			||||||
 | 
					    const program = this.createProgram();
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Check for pre-emit diagnostics first
 | 
				
			||||||
 | 
					    const preEmitDiagnostics = plugins.typescript.getPreEmitDiagnostics(program);
 | 
				
			||||||
 | 
					    const hasPreEmitErrors = this.handleDiagnostics(preEmitDiagnostics);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Only continue to emit phase if no pre-emit errors
 | 
				
			||||||
 | 
					    if (hasPreEmitErrors) {
 | 
				
			||||||
 | 
					      console.error('TypeScript pre-emit checks failed. Please fix the issues above.');
 | 
				
			||||||
 | 
					      process.exit(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // If no pre-emit errors, proceed with emit
 | 
				
			||||||
 | 
					    const emitResult = program.emit();
 | 
				
			||||||
 | 
					    const hasEmitErrors = this.handleDiagnostics(emitResult.diagnostics);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const exitCode = emitResult.emitSkipped ? 1 : 0;
 | 
				
			||||||
 | 
					    if (exitCode === 0) {
 | 
				
			||||||
 | 
					      console.log('TypeScript emit succeeded!');
 | 
				
			||||||
 | 
					      done.resolve(emitResult.emittedFiles);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      console.error('TypeScript emit failed. Please investigate!');
 | 
				
			||||||
 | 
					      process.exit(exitCode);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return done.promise;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Function to check if files can be emitted without actually emitting them
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  public async checkEmit(): Promise<boolean> {
 | 
				
			||||||
 | 
					    console.log(`Checking if ${this.fileNames.length} files can be emitted...`);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Create a program with noEmit option
 | 
				
			||||||
 | 
					    const program = this.createProgram({
 | 
				
			||||||
 | 
					      ...this.options,
 | 
				
			||||||
 | 
					      noEmit: true
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Check for pre-emit diagnostics
 | 
				
			||||||
 | 
					    const preEmitDiagnostics = plugins.typescript.getPreEmitDiagnostics(program);
 | 
				
			||||||
 | 
					    const hasPreEmitErrors = this.handleDiagnostics(preEmitDiagnostics);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // 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 hasEmitErrors = this.handleDiagnostics(emitResult.diagnostics);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    const success = !hasPreEmitErrors && !hasEmitErrors && !emitResult.emitSkipped;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (success) {
 | 
				
			||||||
 | 
					      console.log('TypeScript emit check passed! File can be emitted successfully.');
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      console.error('TypeScript emit check failed. Please fix the issues above.');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return success;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Merges compilerOptions with the default compiler options (backward compatibility)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export const mergeCompilerOptions = (
 | 
				
			||||||
 | 
					  customTsOptions: CompilerOptions,
 | 
				
			||||||
 | 
					  argvArg?: any
 | 
				
			||||||
 | 
					): CompilerOptions => {
 | 
				
			||||||
 | 
					  const tsBuild = new TsBuild();
 | 
				
			||||||
 | 
					  return tsBuild.mergeCompilerOptions(customTsOptions, argvArg);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * The internal main compiler function that compiles the files (backward compatibility)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export const compiler = async (
 | 
				
			||||||
 | 
					  fileNames: string[],
 | 
				
			||||||
 | 
					  options: plugins.typescript.CompilerOptions,
 | 
				
			||||||
 | 
					  argvArg?: any
 | 
				
			||||||
 | 
					): Promise<any[]> => {
 | 
				
			||||||
 | 
					  const tsBuild = new TsBuild(fileNames, options, argvArg);
 | 
				
			||||||
 | 
					  return tsBuild.compile();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Function to check if a TypeScript file can be emitted without actually emitting it (backward compatibility)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export const emitCheck = async (
 | 
				
			||||||
 | 
					  fileNames: string[],
 | 
				
			||||||
 | 
					  options: plugins.typescript.CompilerOptions = {},
 | 
				
			||||||
 | 
					  argvArg?: any
 | 
				
			||||||
 | 
					): Promise<boolean> => {
 | 
				
			||||||
 | 
					  const tsBuild = new TsBuild(fileNames, options, argvArg);
 | 
				
			||||||
 | 
					  return tsBuild.checkEmit();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@@ -1,10 +1,10 @@
 | 
				
			|||||||
import * as plugins from './plugins.js';
 | 
					import * as plugins from './plugins.js';
 | 
				
			||||||
import type { CompilerOptions, ScriptTarget, ModuleKind } from 'typescript';
 | 
					import type { CompilerOptions, ScriptTarget, ModuleKind } from 'typescript';
 | 
				
			||||||
import { compiler, mergeCompilerOptions, emitCheck } from './tsbuild.classes.compiler.js';
 | 
					import { compiler, mergeCompilerOptions, emitCheck } from './tsbuild.classes.tsbuild.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type { CompilerOptions, ScriptTarget, ModuleKind };
 | 
					export type { CompilerOptions, ScriptTarget, ModuleKind };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export * from './tsbuild.classes.compiler.js';
 | 
					export * from './tsbuild.classes.tsbuild.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * compile am array of absolute file paths
 | 
					 * compile am array of absolute file paths
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user