File indexing completed on 2024-06-09 05:44:31
0001 /* 0002 SPDX-FileCopyrightText: 2022 Waqar Ahmed <waqar.17a@gmail.com> 0003 SPDX-FileCopyrightText: 2022 Abdullah <abdullahatta@streetwriters.co> 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 const path = require("path"); 0007 const childProcess = require("child_process"); 0008 0009 process.stdin.resume(); 0010 process.stdin.setEncoding("utf8"); 0011 0012 var text = ""; 0013 0014 process.stdin.on("data", async (data) => { 0015 try { 0016 text += data; 0017 // read till we find a null char 0018 if (text[text.length - 1] !== "\0") { 0019 return; 0020 } 0021 0022 const { filePath, stdinFilePath, source, cursorOffset } = JSON.parse( 0023 text.slice(0, -1) 0024 ); 0025 const prettier = getPrettier(filePath); 0026 text = ""; 0027 0028 if (!prettier) { 0029 const formatted = await prettify( 0030 source, 0031 filePath, 0032 stdinFilePath, 0033 cursorOffset 0034 ); 0035 if (formatted) { 0036 log(formatted); 0037 return; 0038 } 0039 return; 0040 } 0041 0042 if (!prettier) { 0043 console.error("Prettier not found."); 0044 return; 0045 } 0046 0047 const options = await prettier.resolveConfig(filePath, { 0048 useCache: false, 0049 editorconfig: true, 0050 }) || {}; 0051 0052 log( 0053 await prettier.formatWithCursor(source, { 0054 cursorOffset: parseInt(cursorOffset), 0055 filepath: stdinFilePath, 0056 ...options, 0057 }) 0058 ); 0059 } catch (e) { 0060 console.error(e); 0061 } 0062 }); 0063 0064 function tryGetPrettier(lookupPath) { 0065 try { 0066 return require(require.resolve("prettier", { paths: [lookupPath] })); 0067 } catch (e) { 0068 return null; 0069 } 0070 } 0071 0072 function tryGetRootPath(command) { 0073 var globalRootPath = null; 0074 return function () { 0075 if (globalRootPath) return globalRootPath; 0076 try { 0077 return (globalRootPath = childProcess 0078 .execSync(command, { 0079 encoding: "utf8", 0080 }) 0081 .trim()); 0082 } catch (e) { 0083 return null; 0084 } 0085 }; 0086 } 0087 0088 const getVoltaNodeModulesPath = () => 0089 process.env.VOLTA_HOME 0090 ? path.join( 0091 process.env.VOLTA_HOME, 0092 "tools", 0093 "image", 0094 "packages", 0095 "prettier", 0096 "lib" 0097 ) 0098 : null; 0099 const getNpmGlobalRootPath = tryGetRootPath("npm --offline root -g"); 0100 const getYarnGlobalRootPath = tryGetRootPath("yarn --offline global dir"); 0101 0102 const rootPathChecks = [ 0103 path.dirname, 0104 getVoltaNodeModulesPath, 0105 getNpmGlobalRootPath, 0106 getYarnGlobalRootPath, 0107 ]; 0108 0109 function getPrettier(filePath) { 0110 let prettier = null; 0111 for (const check of rootPathChecks) { 0112 const lookupPath = check(filePath); 0113 if (!lookupPath) continue; 0114 0115 prettier = tryGetPrettier(lookupPath); 0116 if (prettier) return prettier; 0117 } 0118 } 0119 0120 async function prettify(code, filePath, stdinFilePath, cursorOffset) { 0121 try { 0122 const prettier = childProcess.spawn( 0123 "prettier", 0124 ["--cursor-offset", cursorOffset, "--stdin-filepath", stdinFilePath], 0125 { cwd: path.dirname(filePath) } 0126 ); 0127 0128 await new Promise((resolve, reject) => 0129 prettier.stdin.end(code, (err) => (err ? reject(err) : resolve())) 0130 ); 0131 0132 return await new Promise((resolve, reject) => { 0133 let formatted = ""; 0134 let error = ""; 0135 0136 prettier.on("close", (status) => { 0137 if (status !== 0) { 0138 reject(error); 0139 } 0140 const resultCursorOffset = parseInt(error); 0141 0142 resolve({ 0143 formatted, 0144 cursorOffset: isNaN(resultCursorOffset) 0145 ? cursorOffset 0146 : resultCursorOffset, 0147 }); 0148 }); 0149 0150 prettier.stdout.on( 0151 "data", 0152 (chunk) => (formatted += chunk.toString("utf-8")) 0153 ); 0154 0155 prettier.stderr.on("data", (chunk) => (error += chunk.toString("utf-8"))); 0156 }); 0157 } catch (e) { 0158 console.error(e); 0159 return null; 0160 } 0161 } 0162 0163 function log(message) { 0164 process.stdout.write(JSON.stringify(message)); 0165 process.stdout.write("[[{END_PRETTIER_SCRIPT}]]"); 0166 }