UNPKG

prettier-plugin-imports

Version:

A prettier plugins to sort imports in provided RegEx order

112 lines (98 loc) 3.39 kB
import { newLineNode, THIRD_PARTY_MODULES_SPECIAL_WORD } from '../constants'; import { getImportNodesMatchedGroup } from './get-import-nodes-matched-group'; import { getSortedImportSpecifiers } from './get-sorted-import-specifiers'; import { getSortedNodesGroup } from './get-sorted-nodes-group'; import { isCustomGroupSeparator, testingOnly, } from './normalize-plugin-options'; import type { GetSortedNodesByImportOrder, ImportGroups, ImportOrLine, } from '../types'; /** * This function returns the given nodes, sorted in the order as indicated by * the importOrder array from the given options. The plugin considers these * import nodes as local import declarations. * * @param originalNodes A subset (of all import nodes) that should be sorted. * @param options Options to influence the behavior of the sorting algorithm. */ export const getSortedNodesByImportOrder: GetSortedNodesByImportOrder = ( originalNodes, { importOrder, importOrderCaseSensitive }, ) => { if ( process.env.NODE_ENV === 'test' && JSON.stringify(importOrder) !== JSON.stringify(testingOnly.normalizeImportOrderOption(importOrder)) ) { throw new Error( 'API Misuse: getSortedNodesByImportOrder::importOrder option already should be normalized.', ); } const finalNodes: ImportOrLine[] = []; const importOrderGroups = importOrder.reduce<ImportGroups>( (groups, regexp) => // Don't create a new group for explicit import separators isCustomGroupSeparator(regexp) ? groups : { ...groups, [regexp]: [], }, {}, ); // Select just the SPECIAL WORDS and the matchers const sanitizedImportOrder = importOrder.filter( (group) => !isCustomGroupSeparator(group) && group !== THIRD_PARTY_MODULES_SPECIAL_WORD, ); // Assign import nodes into import order groups for (const node of originalNodes) { const matchedGroupName = getImportNodesMatchedGroup( node, sanitizedImportOrder, ); const matchedGroup = importOrderGroups[matchedGroupName]; if (matchedGroup) { matchedGroup.push(node); } else { throw new Error( `Could not find a matching group in importOrder for: "${node.source.value}" on line ${node.source.loc?.start.line}.${node.importKind === 'type' ? ' Did you forget to include "<TYPES>"?' : ''}`, ); } } for (const group of importOrder) { // If it's a custom separator, all we need to do is add a newline if (isCustomGroupSeparator(group)) { const lastNode = finalNodes[finalNodes.length - 1]; // Avoid empty new line if first group is empty if (!lastNode) { continue; } // Don't add multiple newlines if (isNodeANewline(lastNode)) { continue; } finalNodes.push(newLineNode); continue; } const groupNodes = importOrderGroups[group]; if (groupNodes.length === 0) continue; const sortedInsideGroup = getSortedNodesGroup(groupNodes, { importOrderCaseSensitive, }); // Sort the import specifiers sortedInsideGroup.forEach((node) => getSortedImportSpecifiers(node, { importOrderCaseSensitive }), ); finalNodes.push(...sortedInsideGroup); } return finalNodes; }; function isNodeANewline(node: ImportOrLine) { return node.type === 'ExpressionStatement'; }