import { Logger, LogLevel } from '../system'; import chalk from 'chalk'; import path from 'path'; import { copyFileWithLock, mkdirIfNotExist, readFileWithLock, writeFileWithLock } from '../utils'; import fs from 'fs'; import { getModuleFile, TsModule } from '../module'; import { patchModule } from './patch-module'; /* ****************************************************************************************************************** */ // region: Types /* ****************************************************************************************************************** */ export interface GetPatchedSourceOptions { log?: Logger skipCache?: boolean skipDts?: boolean } // endregion /* ****************************************************************************************************************** */ // region: Utils /* ****************************************************************************************************************** */ export function getPatchedSource(tsModule: TsModule, options?: GetPatchedSourceOptions): { js: string, dts: string | undefined, loadedFromCache: boolean } { const { backupCachePaths, patchedCachePaths } = tsModule; const { log, skipCache } = options || {}; /* Write backup if not patched */ if (!tsModule.isPatched) { for (const [ key, backupPath ] of Object.entries(backupCachePaths)) { const srcPath = key === 'dts' ? tsModule.dtsPath : tsModule.moduleContentFilePath; if (key === 'dts' && options?.skipDts) continue; if (!srcPath) continue; log?.([ '~', `Writing backup cache to ${chalk.blueBright(backupPath)}` ], LogLevel.verbose); const cacheDir = path.dirname(backupPath); mkdirIfNotExist(cacheDir); copyFileWithLock(srcPath, backupPath); } } /* Get Patched Module */ const canUseCache = !skipCache && !tsModule.moduleFile.patchDetail?.isOutdated && (!patchedCachePaths.dts || fs.existsSync(patchedCachePaths.dts)) && fs.existsSync(patchedCachePaths.js) && !getModuleFile(patchedCachePaths.js).patchDetail?.isOutdated; let js: string | undefined; let dts: string | undefined; if (canUseCache) { js = readFileWithLock(patchedCachePaths.js); dts = !options?.skipDts && patchedCachePaths.dts ? readFileWithLock(patchedCachePaths.dts) : undefined; } else { const res = patchModule(tsModule, options?.skipDts); js = res.js; dts = res.dts; /* Write patched cache */ if (!skipCache) { const cacheDir = path.dirname(patchedCachePaths.js); for (const [ key, patchPath ] of Object.entries(patchedCachePaths)) { const srcPath = key === 'dts' ? dts : js; if (key === 'dts' && options?.skipDts) continue; if (!srcPath) continue; log?.([ '~', `Writing patched cache to ${chalk.blueBright(patchPath)}` ], LogLevel.verbose); mkdirIfNotExist(cacheDir); writeFileWithLock(patchPath, srcPath); } } } return { js, dts, loadedFromCache: canUseCache }; } // endregion