UNPKG

monk-import-export

Version:

Simple import & export sorting ESLint plugin

99 lines (98 loc) 4.34 kB
'use strict'; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.importsRule = void 0; const shared_1 = __importDefault(require("../../utils/shared")); const defaultGroups = [ // Side effect imports. ['^\\u0000'], // Node.js builtins prefixed with `node:`. ['^node:'], // Packages. // Things that start with a letter (or digit or underscore), or `@` followed by a letter. ['^@?\\w'], // Absolute imports and other imports such as Vue-style `@/foo`. // Anything not matched in another group. ['^'], // Relative imports. // Anything that starts with a dot. ['^\\.'] ]; function maybeReportChunkSorting(chunk, context, outerGroups) { const sourceCode = context.getSourceCode(); const items = shared_1.default.getImportExportItems(chunk, sourceCode, isSideEffectImport, getSpecifiers); const sortedItems = makeSortedItems(items, outerGroups); const sorted = shared_1.default.printSortedItems(sortedItems, items, sourceCode); const { start } = items[0]; const { end } = items[items.length - 1]; shared_1.default.maybeReportSorting(context, sorted, start, end); } function makeSortedItems(items, outerGroups) { const itemGroups = outerGroups.map((groups) => groups.map((regex) => ({ regex, items: [] }))); const rest = []; for (const item of items) { const { originalSource } = item.source; const source = item.isSideEffectImport ? `\0${originalSource}` : item.source.kind !== 'value' ? `${originalSource}\0` : originalSource; const [matchedGroup] = shared_1.default .flatMap(itemGroups, (groups) => groups.map((group) => [group, group.regex.exec(source)])) .reduce(([group, longestMatch], [nextGroup, nextMatch]) => nextMatch != null && (longestMatch == null || nextMatch[0].length > longestMatch[0].length) ? [nextGroup, nextMatch] : [group, longestMatch], [undefined, undefined]); if (matchedGroup == null) { rest.push(item); } else { matchedGroup.items.push(item); } } return itemGroups .concat([[{ regex: /^/, items: rest }]]) .map((groups) => groups.filter((group) => group.items.length > 0)) .filter((groups) => groups.length > 0) .map((groups) => groups.map((group) => shared_1.default.sortImportExportItems(group.items))); } // Exclude "ImportDefaultSpecifier" – the "def" in `import def, {a, b}`. function getSpecifiers(importNode) { return importNode.specifiers.filter((node) => isImportSpecifier(node)); } // Full import statement. function isImport(node) { return node.type === 'ImportDeclaration'; } // import def, { a, b as c, type d } from "A" // ^ ^^^^^^ ^^^^^^ function isImportSpecifier(node) { return node.type === 'ImportSpecifier'; } // import "setup" // But not: import {} from "setup" // And not: import type {} from "setup" function isSideEffectImport(importNode, sourceCode) { return (importNode.specifiers.length === 0 && (!importNode.importKind || importNode.importKind === 'value') && !shared_1.default.isPunctuator(sourceCode.getFirstToken(importNode, { skip: 1 }), '{')); } exports.importsRule = { meta: { type: 'layout', fixable: 'code', schema: [ { type: 'object', properties: { groups: { type: 'array', items: { type: 'array', items: { type: 'string' } } } }, additionalProperties: false } ], docs: { url: 'https://github.com/lydell/eslint-plugin-simple-import-sort#sort-order' }, messages: { sort: 'Run autofix to sort these imports!' } }, create: (context) => { const { groups: rawGroups = defaultGroups } = context.options[0] || {}; const outerGroups = rawGroups.map((groups) => groups.map((item) => RegExp(item, 'u'))); return { Program: (programNode) => { for (const chunk of shared_1.default.extractChunks(programNode, (node) => (isImport(node) ? 'PartOfChunk' : 'NotPartOfChunk'))) { maybeReportChunkSorting(chunk, context, outerGroups); } } }; } };