UNPKG

prettier-plugin-multiline-arrays

Version:
85 lines (84 loc) 3.85 kB
import { stringify } from '@augment-vir/common'; import { createWrappedMultiTargetProxy } from 'proxy-vir'; import { pluginMarker } from './plugin-marker.js'; import { multilineArrayPrinter } from './printer/multiline-array-printer.js'; import { setOriginalPrinter } from './printer/original-printer.js'; function addMultilinePrinter(options) { if ('printer' in options) { setOriginalPrinter(options.printer); // overwrite the printer with ours options.printer = multilineArrayPrinter; } else { const astFormat = options.astFormat; if (!astFormat) { throw new Error(`Could not find astFormat while adding printer.`); } /** * If the printer hasn't already been assigned in options, rearrange plugins so that ours * gets chosen. */ const plugins = options.plugins ?? []; const firstMatchedPlugin = plugins.find((plugin) => typeof plugin !== 'string' && !!plugin.printers && !!plugin.printers[astFormat]); if (!firstMatchedPlugin || typeof firstMatchedPlugin === 'string') { throw new Error(`Matched invalid first plugin: ${firstMatchedPlugin}`); } const matchedPrinter = firstMatchedPlugin.printers?.[astFormat]; if (!matchedPrinter) { throw new Error(`Printer not found on matched plugin: ${stringify(firstMatchedPlugin)}`); } setOriginalPrinter(matchedPrinter); const thisPluginIndex = plugins.findIndex((plugin) => { return plugin.pluginMarker === pluginMarker; }); const thisPlugin = plugins[thisPluginIndex]; if (!thisPlugin) { throw new Error(`This plugin was not found.`); } // remove this plugin from its current location in the array plugins.splice(thisPluginIndex, 1); // add this plugin to the beginning of the array so its printer is found first plugins.splice(0, 0, thisPlugin); } } function findPluginsByParserName(parserName, plugins) { return plugins.filter((plugin) => { return (typeof plugin === 'object' && plugin.pluginMarker !== pluginMarker && !!plugin.parsers?.[parserName]); }); } export function wrapParser(originalParser, parserName) { /** Create a multi-target proxy of parsers so that we don't block other plugins. */ const parserProxy = createWrappedMultiTargetProxy({ initialTarget: originalParser, }); function multilineArraysPluginPreprocess(text, options) { const pluginsFromOptions = options.plugins ?? []; const pluginsWithRelevantParsers = findPluginsByParserName(parserName, pluginsFromOptions); pluginsWithRelevantParsers.forEach((plugin) => { const currentParser = plugin.parsers?.[parserName]; if (currentParser && plugin?.name?.includes('prettier-plugin-sort-json')) { parserProxy.proxyModifier.addOverrideTarget(currentParser); } }); const pluginsWithPreprocessor = pluginsWithRelevantParsers.filter((plugin) => !!plugin.parsers?.[parserName]?.preprocess); let processedText = text; pluginsWithPreprocessor.forEach((pluginWithPreprocessor) => { const nextText = pluginWithPreprocessor.parsers?.[parserName]?.preprocess?.(processedText, { ...options, plugins: pluginsFromOptions.filter((plugin) => plugin.pluginMarker !== pluginMarker), }); if (nextText != undefined) { processedText = nextText; } }); addMultilinePrinter(options); return processedText; } parserProxy.proxyModifier.addOverrideTarget({ preprocess: multilineArraysPluginPreprocess, }); return parserProxy.proxy; }