From 886b0ff2e5cdd1ec711b1e88166846d4ec632532 Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Tue, 18 Feb 2025 14:40:49 +0000 Subject: [PATCH] feat: support custom parsers Adds support for custom parsers in the `--parser` option. This wasn't previously supported since the option is defined with a hard coded enum of the default parsers. --- src/bin.ts | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/bin.ts b/src/bin.ts index ba3a6e3..cdc098d 100644 --- a/src/bin.ts +++ b/src/bin.ts @@ -7,6 +7,8 @@ import { getPlugin, isBoolean, isNumber, isIntegerInRange, isString } from "./ut import { normalizeOptions, normalizeFormatOptions, normalizePluginOptions } from "./utils.js"; import type { Bin, PluginsOptions } from "./types.js"; +const defaultParsers = ["flow", "babel", "babel-flow", "babel-ts", "typescript", "acorn", "espree", "meriyah", "css", "less", "scss", "json", "json5", "json-stringify", "graphql", "markdown", "mdx", "vue", "yaml", "glimmer", "html", "angular", "lwc"]; + const makeBin = (): Bin => { return ( bin("prettier", "An opinionated code formatter") @@ -63,9 +65,9 @@ const makeBin = (): Bin => { .option("--jsx-single-quote", 'Use single quotes in JSX\nDefaults to "false"', { section: "Format", }) - .option("--parser ", "Which parser to use", { + .option(`--parser <${defaultParsers.join('|')}>`, "Which parser to use", { section: "Format", - enum: ["flow", "babel", "babel-flow", "babel-ts", "typescript", "acorn", "espree", "meriyah", "css", "less", "scss", "json", "json5", "json-stringify", "graphql", "markdown", "mdx", "vue", "yaml", "glimmer", "html", "angular", "lwc"], + enum: defaultParsers, }) .option("--print-width ", 'The line length where Prettier will try wrap\nDefaults to "80"', { section: "Format", @@ -204,11 +206,18 @@ const makePluggableBin = async (): Promise => { const pluginsDefaultOptions: PluginsOptions = {}; const pluginsNames = formatOptions.plugins || []; const optionsNames: string[] = []; + const parserNames = new Set(); for (let i = 0, l = pluginsNames.length; i < l; i++) { const pluginName = pluginsNames[i]; const plugin = await getPlugin(pluginName); + if (plugin.parsers) { + for (const key of Object.keys(plugin.parsers)) { + parserNames.add(key); + } + } + for (const option in plugin.options) { optionsNames.push(option); Object.assign(pluginsDefaultOptions, plugin.defaultOptions); @@ -254,6 +263,16 @@ const makePluggableBin = async (): Promise => { } } + if (parserNames.size > 0) { + const allParserNames = [...defaultParsers, ...parserNames]; + // TODO (43081j): this doesn't work! tiny-bin won't let you override + // an already defined option + bin.option(`--parser <${allParserNames}>`, "Which parser to use", { + section: "Format", + enum: defaultParsers, + }); + } + bin = bin.action(async (options, files) => { const { run } = await import("./index.js"); const baseOptions = await normalizeOptions(options, files);