Compare commits
	
		
			2 Commits
		
	
	
		
			v2.3.0
			...
			5ecf4b7125
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 5ecf4b7125 | |||
| 2aa6348cdd | 
@@ -1,5 +1,12 @@
 | 
			
		||||
# 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)
 | 
			
		||||
Add emitcheck command to validate TS file emission without generating output
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@git.zone/tsbuild",
 | 
			
		||||
  "version": "2.3.0",
 | 
			
		||||
  "version": "2.3.1",
 | 
			
		||||
  "private": false,
 | 
			
		||||
  "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",
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,6 @@
 | 
			
		||||
 */
 | 
			
		||||
export const commitinfo = {
 | 
			
		||||
  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.'
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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 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 * from './tsbuild.classes.compiler.js';
 | 
			
		||||
export * from './tsbuild.classes.tsbuild.js';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * compile am array of absolute file paths
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user