UNPKG

eslint-plugin-perfectionist

Version:

ESLint plugin for sorting various data such as objects, imports, types, enums, JSX props, etc.

159 lines (158 loc) 5.23 kB
'use strict' const commonJsonSchemas = require('../utils/common-json-schemas.js') const validateCustomSortConfiguration = require('../utils/validate-custom-sort-configuration.js') const getEslintDisabledLines = require('../utils/get-eslint-disabled-lines.js') const isNodeEslintDisabled = require('../utils/is-node-eslint-disabled.js') const createEslintRule = require('../utils/create-eslint-rule.js') const reportAllErrors = require('../utils/report-all-errors.js') const shouldPartition = require('../utils/should-partition.js') const rangeToDiff = require('../utils/range-to-diff.js') const reportErrors = require('../utils/report-errors.js') const getSettings = require('../utils/get-settings.js') const isSortable = require('../utils/is-sortable.js') const sortNodes = require('../utils/sort-nodes.js') const complete = require('../utils/complete.js') let defaultOptions = { fallbackSort: { type: 'unsorted' }, specialCharacters: 'keep', partitionByNewLine: false, partitionByComment: false, type: 'alphabetical', ignoreAlias: false, groupKind: 'mixed', ignoreCase: true, locales: 'en-US', alphabet: '', order: 'asc', } const sortNamedExports = createEslintRule.createEslintRule({ create: context => ({ ExportNamedDeclaration: node => { var _a if (!isSortable.isSortable(node.specifiers)) { return } let settings = getSettings.getSettings(context.settings) let options = complete.complete( context.options.at(0), settings, defaultOptions, ) validateCustomSortConfiguration.validateCustomSortConfiguration(options) let { sourceCode, id } = context let eslintDisabledLines = getEslintDisabledLines.getEslintDisabledLines({ ruleName: id, sourceCode, }) let formattedMembers = [[]] for (let specifier of node.specifiers) { let name if (options.ignoreAlias) { if (specifier.local.type === 'Identifier') { ;({ name } = specifier.local) } else { name = specifier.local.value } } else { if (specifier.exported.type === 'Identifier') { ;({ name } = specifier.exported) } else { name = specifier.exported.value } } let lastSortingNode = (_a = formattedMembers.at(-1)) == null ? void 0 : _a.at(-1) let sortingNode = { isEslintDisabled: isNodeEslintDisabled.isNodeEslintDisabled( specifier, eslintDisabledLines, ), groupKind: specifier.exportKind === 'type' ? 'type' : 'value', size: rangeToDiff.rangeToDiff(specifier, sourceCode), node: specifier, name, } if ( shouldPartition.shouldPartition({ lastSortingNode, sortingNode, sourceCode, options, }) ) { formattedMembers.push([]) } formattedMembers.at(-1).push(sortingNode) } let groupKindOrder if (options.groupKind === 'values-first') { groupKindOrder = ['value', 'type'] } else if (options.groupKind === 'types-first') { groupKindOrder = ['type', 'value'] } else { groupKindOrder = ['any'] } for (let nodes of formattedMembers) { let filteredGroupKindNodes = groupKindOrder.map(groupKind => nodes.filter( currentNode => groupKind === 'any' || currentNode.groupKind === groupKind, ), ) let sortNodesExcludingEslintDisabled = ignoreEslintDisabledNodes => filteredGroupKindNodes.flatMap(groupedNodes => sortNodes.sortNodes({ ignoreEslintDisabledNodes, nodes: groupedNodes, options, }), ) reportAllErrors.reportAllErrors({ availableMessageIds: { unexpectedOrder: 'unexpectedNamedExportsOrder', }, sortNodesExcludingEslintDisabled, sourceCode, options, context, nodes, }) } }, }), meta: { schema: [ { properties: { ...commonJsonSchemas.commonJsonSchemas, groupKind: { enum: ['mixed', 'values-first', 'types-first'], description: 'Specifies top-level groups.', type: 'string', }, ignoreAlias: { description: 'Controls whether to ignore alias names.', type: 'boolean', }, partitionByComment: commonJsonSchemas.partitionByCommentJsonSchema, partitionByNewLine: commonJsonSchemas.partitionByNewLineJsonSchema, }, additionalProperties: false, type: 'object', }, ], docs: { url: 'https://perfectionist.dev/rules/sort-named-exports', description: 'Enforce sorted named exports.', recommended: true, }, messages: { unexpectedNamedExportsOrder: reportErrors.ORDER_ERROR, }, type: 'suggestion', fixable: 'code', }, defaultOptions: [defaultOptions], name: 'sort-named-exports', }) module.exports = sortNamedExports