prettier-plugin-multiline-arrays
Version:
Prettier plugin to force all arrays to be multiline.
73 lines (72 loc) • 3.08 kB
JavaScript
import { envDebugKey, fillInOptions } from '../options.js';
import { printWithMultilineArrays } from './insert-new-lines.js';
import { getOriginalPrinter } from './original-printer.js';
const debug = !!process.env[envDebugKey];
function wrapInOriginalPrinterCall(property, subProperty) {
return (...args) => {
const originalPrinter = getOriginalPrinter();
if (property === 'print') {
const path = args[0];
const options = args[1];
const originalOutput = originalPrinter.print.call(originalPrinter, path, options, ...args.slice(2));
if (options.filepath?.endsWith('package.json') &&
options.plugins.some((plugin) => typeof plugin === 'object' &&
plugin.name?.includes('prettier-plugin-packagejson'))) {
return originalOutput;
}
const multilineOptions = fillInOptions(options);
const multilinePrintedOutput = printWithMultilineArrays(originalOutput, args[0], multilineOptions, debug);
return multilinePrintedOutput;
}
else {
let thisParent = originalPrinter;
let printerProp = originalPrinter[property];
if (subProperty) {
thisParent = printerProp;
printerProp = printerProp[subProperty];
}
try {
return printerProp?.apply(thisParent, args);
}
catch (error) {
const newError = new Error(`Failed to wrap JS printer call for property "${property}" ${subProperty ? `and subProperty "${subProperty}"` : ''}: \n`);
if (error instanceof Error && error.stack) {
newError.stack = newError.message + error.stack;
}
throw newError;
}
}
};
}
const handleComments = {
endOfLine: wrapInOriginalPrinterCall('handleComments', 'endOfLine'),
ownLine: wrapInOriginalPrinterCall('handleComments', 'ownLine'),
remaining: wrapInOriginalPrinterCall('handleComments', 'remaining'),
};
/** This is a proxy because the original printer is only set at run time. */
export const multilineArrayPrinter = new Proxy({}, {
get: (target, property) => {
// @ts-expect-error: the avoidAstMutation property is not defined in the types
if (property === 'experimentalFeatures') {
return {
avoidAstMutation: true,
};
}
/**
* "handleComments" is the only printer property which isn't a callback function, so for
* simplicity, ignore it.
*/
if (property === 'handleComments') {
return handleComments;
}
const originalPrinter = getOriginalPrinter();
if (originalPrinter[property] === undefined) {
return undefined;
}
/**
* We have to return a callback so that we can extract the jsPlugin from the options
* argument
*/
return wrapInOriginalPrinterCall(property);
},
});