mirror of https://github.com/msgbyte/tailchat
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			149 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			149 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			TypeScript
		
	
import ts from 'typescript';
 | 
						|
import fs from 'fs-extra';
 | 
						|
import ora from 'ora';
 | 
						|
import { glob } from 'glob';
 | 
						|
import path from 'path';
 | 
						|
import execa from 'execa';
 | 
						|
 | 
						|
async function buildTailchatServer() {
 | 
						|
  const spinner = ora({
 | 
						|
    prefixText: 'Tailchat Server',
 | 
						|
  });
 | 
						|
 | 
						|
  try {
 | 
						|
    spinner.start('Start compiling');
 | 
						|
    await fs.remove('./dist');
 | 
						|
    spinner.info('Compiling TS code');
 | 
						|
    await compileTsCode();
 | 
						|
    spinner.info('Moving static resource files');
 | 
						|
    await Promise.all([
 | 
						|
      fs.copy('./public', './dist/public', { recursive: true }),
 | 
						|
      fs.copy('./locales', './dist/locales', { recursive: true }),
 | 
						|
      fs.copy('./views', './dist/views', { recursive: true }),
 | 
						|
      fs.copy(
 | 
						|
        './services/openapi/oidc/views',
 | 
						|
        './dist/services/openapi/oidc/views',
 | 
						|
        { recursive: true }
 | 
						|
      ),
 | 
						|
    ]);
 | 
						|
 | 
						|
    if (process.platform !== 'win32' || (await isAdmin())) {
 | 
						|
      spinner.info('Building plugin dependent symlink');
 | 
						|
      const nodeModulesList = await glob('./plugins/*/node_modules/*');
 | 
						|
      for (const item of nodeModulesList) {
 | 
						|
        const src = path.resolve(__dirname, '../', item);
 | 
						|
        const dest = path.resolve(__dirname, '../dist', item);
 | 
						|
 | 
						|
        spinner.text = `Building Symlink: ${src} -> ${dest}`;
 | 
						|
 | 
						|
        await fs.createSymlink(src, dest, 'dir');
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      spinner.warn(
 | 
						|
        'You are run command in windows without admin permit, create symlink will be skip'
 | 
						|
      );
 | 
						|
    }
 | 
						|
 | 
						|
    spinner.succeed('Compiled!');
 | 
						|
  } catch (e) {
 | 
						|
    console.error(e);
 | 
						|
    spinner.fail('Compilation failed!');
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
buildTailchatServer();
 | 
						|
 | 
						|
/**
 | 
						|
 * 编译Ts代码
 | 
						|
 *
 | 
						|
 * tsc的api实现
 | 
						|
 */
 | 
						|
function compileTsCode(): Promise<void> {
 | 
						|
  function compile(
 | 
						|
    fileNames: string[],
 | 
						|
    options: ts.CompilerOptions
 | 
						|
  ): Promise<void> {
 | 
						|
    return new Promise<void>((resolve, reject) => {
 | 
						|
      const program = ts.createProgram(fileNames, options);
 | 
						|
      const emitResult = program.emit();
 | 
						|
 | 
						|
      const allDiagnostics = ts
 | 
						|
        .getPreEmitDiagnostics(program)
 | 
						|
        .concat(emitResult.diagnostics);
 | 
						|
 | 
						|
      allDiagnostics.forEach((diagnostic) => {
 | 
						|
        if (diagnostic.file) {
 | 
						|
          const { line, character } = ts.getLineAndCharacterOfPosition(
 | 
						|
            diagnostic.file,
 | 
						|
            diagnostic.start!
 | 
						|
          );
 | 
						|
          const message = ts.flattenDiagnosticMessageText(
 | 
						|
            diagnostic.messageText,
 | 
						|
            '\n'
 | 
						|
          );
 | 
						|
          console.log(
 | 
						|
            `${diagnostic.file.fileName} (${line + 1},${
 | 
						|
              character + 1
 | 
						|
            }): ${message}`
 | 
						|
          );
 | 
						|
        } else {
 | 
						|
          console.log(
 | 
						|
            ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')
 | 
						|
          );
 | 
						|
        }
 | 
						|
      });
 | 
						|
 | 
						|
      const exitCode = emitResult.emitSkipped ? 1 : 0;
 | 
						|
      if (exitCode === 0) {
 | 
						|
        resolve();
 | 
						|
      } else {
 | 
						|
        reject();
 | 
						|
      }
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  const configPath = ts.findConfigFile(
 | 
						|
    process.cwd() /*searchPath*/,
 | 
						|
    ts.sys.fileExists,
 | 
						|
    'tsconfig.json'
 | 
						|
  );
 | 
						|
  const configFile = ts.readJsonConfigFile(configPath, ts.sys.readFile);
 | 
						|
  const { fileNames, options } = ts.parseJsonSourceFileConfigFileContent(
 | 
						|
    configFile,
 | 
						|
    ts.sys,
 | 
						|
    process.cwd()
 | 
						|
  );
 | 
						|
 | 
						|
  return compile(fileNames, options);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * check is window admin
 | 
						|
 */
 | 
						|
async function isAdmin() {
 | 
						|
  if (process.platform !== 'win32') {
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  try {
 | 
						|
    // https://stackoverflow.com/a/21295806/1641422
 | 
						|
    await execa('fsutil', ['dirty', 'query', process.env.systemdrive]);
 | 
						|
    return true;
 | 
						|
  } catch (error) {
 | 
						|
    if (error.code === 'ENOENT') {
 | 
						|
      return testFltmc();
 | 
						|
    }
 | 
						|
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
async function testFltmc() {
 | 
						|
  try {
 | 
						|
    await execa('fltmc');
 | 
						|
    return true;
 | 
						|
  } catch {
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
}
 |