import { existsSync } from 'fs' ; import { join , dirname } from 'path' ; import type { Options } from '@swc-node/core' ; import chalk from 'chalk' ; import debugFactory from 'debug' ; import * as ts from 'typescript' ; const debug = debugFactory ( '@swc-node' ) ; export function readDefaultTsConfig ( tsConfigPath = process . env . SWC_NODE_PROJECT ?? process . env . TS_NODE_PROJECT ?? join ( process . cwd ( ) , 'tsconfig.json' ) ) { let compilerOptions = { target : ts . ScriptTarget . ES2018 , module : ts . ModuleKind . CommonJS , moduleResolution : ts . ModuleResolutionKind . NodeJs , sourceMap : true , esModuleInterop : true , } ; if ( tsConfigPath && existsSync ( tsConfigPath ) ) { try { debug ( `Read config file from ${ tsConfigPath }` ) ; const { config } = ts . readConfigFile ( tsConfigPath , ts . sys . readFile ) ; const { options , errors , fileNames } = ts . parseJsonConfigFileContent ( config , ts . sys , dirname ( tsConfigPath ) ) ; if ( ! errors . length ) { compilerOptions = options ; compilerOptions . files = fileNames ; } else { console . info ( chalk . yellow ( `Convert compiler options from json failed, ${ errors . map ( ( d ) => d . messageText ) . join ( '\n' ) }` ) ) ; } } catch ( e ) { console . info ( chalk . yellow ( `Read ${ tsConfigPath } failed: ${ ( e as Error ) . message }` ) ) ; } } return compilerOptions ; } function toTsTarget ( target ) { switch ( target ) { case ts . ScriptTarget . ES3 : return 'es3' ; case ts . ScriptTarget . ES5 : return 'es5' ; case ts . ScriptTarget . ES2015 : return 'es2015' ; case ts . ScriptTarget . ES2016 : return 'es2016' ; case ts . ScriptTarget . ES2017 : return 'es2017' ; case ts . ScriptTarget . ES2018 : return 'es2018' ; case ts . ScriptTarget . ES2019 : return 'es2019' ; case ts . ScriptTarget . ES2020 : return 'es2020' ; case ts . ScriptTarget . ES2021 : case ts . ScriptTarget . ESNext : case ts . ScriptTarget . Latest : return 'es2021' ; case ts . ScriptTarget . JSON : return 'es5' ; } } function toModule ( moduleKind ) { switch ( moduleKind ) { case ts . ModuleKind . CommonJS : return 'commonjs' ; case ts . ModuleKind . UMD : return 'umd' ; case ts . ModuleKind . AMD : return 'amd' ; case ts . ModuleKind . ES2015 : case ts . ModuleKind . ES2020 : case ts . ModuleKind . ES2022 : case ts . ModuleKind . ESNext : case ts . ModuleKind . Node12 : case ts . ModuleKind . NodeNext : case ts . ModuleKind . None : return 'es6' ; case ts . ModuleKind . System : throw new TypeError ( 'Do not support system kind module' ) ; } } export function createSourcemapOption ( options ) { return options . sourceMap !== false ? options . inlineSourceMap ? 'inline' : true : options . inlineSourceMap ? 'inline' : false ; } export function tsCompilerOptionsToSwcConfig ( options , filename ) { return { target : toTsTarget ( options . target ?? ts . ScriptTarget . ES2018 ) , module : toModule ( options . module ?? ts . ModuleKind . ES2015 ) , sourcemap : createSourcemapOption ( options ) , jsx : filename . endsWith ( '.tsx' ) || filename . endsWith ( '.jsx' ) || Boolean ( options . jsx ) , react : options . jsxFactory || options . jsxFragmentFactory || options . jsx || options . jsxImportSource ? { pragma : options . jsxFactory , pragmaFrag : options . jsxFragmentFactory , importSource : options . jsxImportSource , runtime : ( options . jsx ?? 0 ) >= ts . JsxEmit . ReactJSX ? 'automatic' : 'classic' , } : undefined , experimentalDecorators : options . experimentalDecorators ?? false , emitDecoratorMetadata : options . emitDecoratorMetadata ?? false , dynamicImport : true , esModuleInterop : options . esModuleInterop ?? false , keepClassNames : true , } ; }