keycloak_theme/src/bin/tools/runPrettier.ts

128 lines
3.6 KiB
TypeScript
Raw Normal View History

2024-11-02 22:39:03 +01:00
import { getNodeModulesBinDirPath } from "./nodeModulesBinDirPath";
import { join as pathJoin, resolve as pathResolve } from "path";
2024-11-02 22:39:03 +01:00
import * as fsPr from "fs/promises";
import { id } from "tsafe/id";
import { assert } from "tsafe/assert";
import chalk from "chalk";
2024-11-17 19:22:34 +01:00
import * as crypto from "crypto";
import { is } from "tsafe/is";
import { symToStr } from "tsafe/symToStr";
import { readThisNpmPackageVersion } from "./readThisNpmPackageVersion";
2024-11-02 22:39:03 +01:00
getIsPrettierAvailable.cache = id<boolean | undefined>(undefined);
export async function getIsPrettierAvailable(): Promise<boolean> {
if (getIsPrettierAvailable.cache !== undefined) {
return getIsPrettierAvailable.cache;
}
const nodeModulesBinDirPath = getNodeModulesBinDirPath();
const prettierBinPath = pathJoin(nodeModulesBinDirPath, "prettier");
const stats = await fsPr.stat(prettierBinPath).catch(() => undefined);
const isPrettierAvailable = stats?.isFile() ?? false;
getIsPrettierAvailable.cache = isPrettierAvailable;
return isPrettierAvailable;
}
2024-11-17 19:22:34 +01:00
type PrettierAndConfigHash = {
2024-11-02 22:39:03 +01:00
prettier: typeof import("prettier");
2024-11-17 19:22:34 +01:00
configHash: string;
2024-11-02 22:39:03 +01:00
};
2024-11-17 19:22:34 +01:00
getPrettier.cache = id<PrettierAndConfigHash | undefined>(undefined);
2024-11-02 22:39:03 +01:00
2024-11-17 19:22:34 +01:00
export async function getPrettier(): Promise<PrettierAndConfigHash> {
2024-11-02 22:39:03 +01:00
assert(getIsPrettierAvailable());
2024-11-17 19:22:34 +01:00
if (getPrettier.cache !== undefined) {
return getPrettier.cache;
2024-11-02 22:39:03 +01:00
}
let prettier = id<typeof import("prettier") | undefined>(undefined);
import_prettier: {
// NOTE: When module is linked we want to make sure we import the correct version
// of prettier, that is the one of the project, not the one of this repo.
// So we do a sketchy eval to bypass ncc.
// We make sure to only do that when linking, otherwise we import properly.
if (readThisNpmPackageVersion() === "0.0.0") {
eval(
`${symToStr({ prettier })} = require("${pathResolve(pathJoin(getNodeModulesBinDirPath(), "..", "prettier"))}")`
);
assert(!is<undefined>(prettier));
break import_prettier;
}
prettier = await import("prettier");
}
2024-11-02 22:39:03 +01:00
2024-11-17 19:22:34 +01:00
const configHash = await (async () => {
const configFilePath = await prettier.resolveConfigFile(
pathJoin(getNodeModulesBinDirPath(), "..")
);
if (configFilePath === null) {
return "";
}
const data = await fsPr.readFile(configFilePath);
return crypto.createHash("sha256").update(data).digest("hex");
})();
const prettierAndConfig: PrettierAndConfigHash = {
2024-11-02 22:39:03 +01:00
prettier,
2024-11-17 19:22:34 +01:00
configHash
2024-11-02 22:39:03 +01:00
};
2024-11-17 19:22:34 +01:00
getPrettier.cache = prettierAndConfig;
2024-11-02 22:39:03 +01:00
return prettierAndConfig;
}
export async function runPrettier(params: {
sourceCode: string;
filePath: string;
}): Promise<string> {
const { sourceCode, filePath } = params;
let formattedSourceCode: string;
try {
2024-11-17 19:22:34 +01:00
const { prettier } = await getPrettier();
2024-11-02 22:39:03 +01:00
2024-11-16 21:37:14 +01:00
const { ignored, inferredParser } = await prettier.getFileInfo(filePath, {
resolveConfig: true
});
if (ignored) {
return sourceCode;
}
2024-11-17 19:22:34 +01:00
const config = await prettier.resolveConfig(filePath);
2024-11-16 21:37:14 +01:00
formattedSourceCode = await prettier.format(sourceCode, {
...config,
filePath,
parser: inferredParser ?? undefined
});
2024-11-02 22:39:03 +01:00
} catch (error) {
console.log(
chalk.red(
`You probably need to upgrade the version of prettier in your project`
)
);
throw error;
}
return formattedSourceCode;
}