1import childProcess from "child_process"; 2import fs from "fs-extra"; 3import path from "path"; 4import glob from "glob"; 5import url from "url"; 6 7const __filename = url.fileURLToPath(new URL(import.meta.url)); 8const __dirname = path.dirname(__filename); 9 10const root = path.join(__dirname, ".."); 11const source = path.join(root, "built/local"); 12const dest = path.join(root, "lib"); 13const copyright = fs.readFileSync(path.join(__dirname, "../CopyrightNotice.txt"), "utf-8"); 14 15async function produceLKG() { 16 console.log(`Building LKG from ${source} to ${dest}`); 17 await copyLibFiles(); 18 await copyLocalizedDiagnostics(); 19 await copyTypesMap(); 20 await copyScriptOutputs(); 21 await copyDeclarationOutputs(); 22 await buildProtocol(); 23 await writeGitAttributes(); 24} 25 26async function copyLibFiles() { 27 await copyFilesWithGlob("lib?(.*).d.ts"); 28} 29 30async function copyLocalizedDiagnostics() { 31 const dir = await fs.readdir(source); 32 const ignoredFolders = ["enu"]; 33 34 for (const d of dir) { 35 const fileName = path.join(source, d); 36 if ( 37 fs.statSync(fileName).isDirectory() && 38 ignoredFolders.indexOf(d) < 0 39 ) { 40 await fs.copy(fileName, path.join(dest, d)); 41 } 42 } 43} 44 45async function copyTypesMap() { 46 await copyFromBuiltLocal("typesMap.json"); // Cannot accommodate copyright header 47} 48 49async function buildProtocol() { 50 const protocolScript = path.join(__dirname, "buildProtocol.mjs"); 51 if (!fs.existsSync(protocolScript)) { 52 throw new Error(`Expected protocol script ${protocolScript} to exist`); 53 } 54 55 const protocolInput = path.join(__dirname, "../src/server/protocol.ts"); 56 const protocolServices = path.join(source, "typescriptServices.d.ts"); 57 const protocolOutput = path.join(dest, "protocol.d.ts"); 58 59 console.log(`Building ${protocolOutput}...`); 60 await exec(protocolScript, [protocolInput, protocolServices, protocolOutput]); 61} 62 63async function copyScriptOutputs() { 64 await copyWithCopyright("cancellationToken.js"); 65 await copyWithCopyright("tsc.release.js", "tsc.js"); 66 await copyWithCopyright("tsserver.js"); 67 await copyWithCopyright("dynamicImportCompat.js"); 68 await copyFromBuiltLocal("tsserverlibrary.js"); // copyright added by build 69 await copyFromBuiltLocal("typescript.js"); // copyright added by build 70 await copyFromBuiltLocal("typescriptServices.js"); // copyright added by build 71 await copyWithCopyright("typingsInstaller.js"); 72 await copyWithCopyright("watchGuard.js"); 73} 74 75async function copyDeclarationOutputs() { 76 await copyFromBuiltLocal("tsserverlibrary.d.ts"); // copyright added by build 77 await copyFromBuiltLocal("typescript.d.ts"); // copyright added by build 78 await copyFromBuiltLocal("typescriptServices.d.ts"); // copyright added by build 79} 80 81async function writeGitAttributes() { 82 await fs.writeFile(path.join(dest, ".gitattributes"), `* text eol=lf`, "utf-8"); 83} 84 85/** 86 * @param {string} fileName 87 * @param {string} destName 88 */ 89async function copyWithCopyright(fileName, destName = fileName) { 90 const content = await fs.readFile(path.join(source, fileName), "utf-8"); 91 await fs.writeFile(path.join(dest, destName), copyright + "\n" + content); 92} 93 94/** 95 * @param {string} fileName 96 */ 97async function copyFromBuiltLocal(fileName) { 98 await fs.copy(path.join(source, fileName), path.join(dest, fileName)); 99} 100 101/** 102 * @param {string} pattern 103 */ 104async function copyFilesWithGlob(pattern) { 105 const files = glob.sync(pattern, { cwd: source }).map(f => path.basename(f)); 106 for (const f of files) { 107 await copyFromBuiltLocal(f); 108 } 109 console.log(`Copied ${files.length} files matching pattern ${pattern}`); 110} 111 112/** 113 * @param {string} path 114 * @param {string[]} args 115 */ 116async function exec(path, args = []) { 117 const cmdLine = ["node", path, ...args].join(" "); 118 console.log(cmdLine); 119 childProcess.execSync(cmdLine); 120} 121 122process.on("unhandledRejection", err => { 123 throw err; 124}); 125produceLKG().then(() => console.log("Done"), err => { 126 throw err; 127}); 128