Files
test-repo/tests/config/format-test/run-prettier.js
T

104 lines
2.7 KiB
JavaScript

import fs from "node:fs";
import getPrettier from "../get-prettier.js";
import {
CURSOR_PLACEHOLDER,
isProduction,
TEST_RUNTIME,
TEST_STANDALONE,
} from "./constants.js";
import { ensurePromise } from "./utilities.js";
import visualizeEndOfLine from "./visualize-end-of-line.js";
async function parse(input, options) {
const prettier = await getPrettier();
const { ast } = await ensurePromise(
prettier.__debug.parse(input, await loadPlugins(options), {
massage: true,
}),
);
return ast;
}
async function format(input, options) {
const inputWithCursor = insertCursor(input, options.cursorOffset);
const prettier = await getPrettier();
const { formatted: output, cursorOffset } = await ensurePromise(
prettier.formatWithCursor(input, await loadPlugins(options)),
);
const outputWithCursor = insertCursor(output, cursorOffset);
const eolVisualizedOutput = visualizeEndOfLine(outputWithCursor);
const changed = outputWithCursor !== inputWithCursor;
return {
changed,
options,
input,
inputWithCursor,
output,
outputWithCursor,
eolVisualizedOutput,
};
}
const insertCursor = (text, cursorOffset) =>
cursorOffset >= 0
? text.slice(0, cursorOffset) +
CURSOR_PLACEHOLDER +
text.slice(cursorOffset)
: text;
// Move this to prettier installation
let externalParsers;
async function loadPlugins(options) {
if (!isProduction || !options.parser || TEST_RUNTIME === "browser") {
return options;
}
const { parser } = options;
if (!externalParsers) {
externalParsers = getExternalPlugins();
}
externalParsers = await externalParsers;
if (!externalParsers.has(parser)) {
return options;
}
const plugin = externalParsers.get(parser);
const plugins = options.plugins ?? [];
plugins.push(TEST_STANDALONE ? plugin.implementation : plugin.url);
return { ...options, plugins };
}
async function getExternalPlugins() {
const distDirectory = new URL("../../../dist/", import.meta.url);
const directories = fs.readdirSync(distDirectory);
const plugins = await Promise.all(
directories
.filter((directory) => directory.startsWith("plugin-"))
.map(async (directory) => {
const url = new URL(`./${directory}/index.mjs`, distDirectory);
const implementation = await import(url);
return {
url,
implementation,
};
}),
);
const externalParsers = new Map();
for (const plugin of plugins) {
const { parsers } = plugin.implementation;
if (parsers) {
for (const parser of Object.keys(parsers)) {
externalParsers.set(parser, plugin);
}
}
}
return externalParsers;
}
export { format, parse };