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 }