UNPKG

@sumup-oss/eslint-plugin-circuit-ui

Version:
150 lines (149 loc) 5.7 kB
"use strict"; /** * Copyright 2023, SumUp Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.componentLifecycleImports = void 0; const utils_1 = require("@typescript-eslint/utils"); /* eslint-disable */ const createRule = utils_1.ESLintUtils.RuleCreator((name) => `https://github.com/sumup-oss/circuit-ui/tree/main/packages/eslint-plugin-circuit-ui/${name}`); const mappings = [ { from: '@sumup-oss/circuit-ui', to: '@sumup-oss/circuit-ui/legacy', specifiers: [ 'RadioButton', 'RadioButtonProps', 'RangePicker', 'RangePickerProps', 'RangePickerController', 'RangePickerControllerProps', 'Selector', 'SelectorProps', 'SingleDayPicker', 'SingleDayPickerProps', 'CalendarConstants', 'CalendarTag', 'CalendarTagProps', 'CalendarTagTwoStep', 'CalendarTagTwoStepProps', 'Grid', 'Row', 'Col', 'ColProps', 'InlineElements', 'InlineElementsProps', 'Header', 'HeaderProps', 'Sidebar', 'SidebarProps', 'SidebarContextProvider', 'SidebarContextConsumer', 'uniqueId', 'cx', 'spacing', 'shadow', 'disableVisually', 'hideVisually', 'focusOutline', 'focusVisible', 'clearfix', 'hideScrollbar', 'inputOutline', 'typography', 'center', ], }, { from: '@sumup-oss/circuit-ui/experimental', to: '@sumup-oss/circuit-ui', specifiers: [ 'Calendar', 'CalendarProps', 'PlainDateRange', 'ColorInput', 'ColorInputProps', 'PhoneNumberInputProps', 'PhoneNumberInput', 'Tooltip', 'TooltipProps', 'TooltipReferenceProps', 'Toggletip', 'ToggletipProps', 'Timestamp', 'TimestampProps', ], }, ]; exports.componentLifecycleImports = createRule({ name: 'component-lifecycle-imports', meta: { type: 'suggestion', schema: [], fixable: 'code', docs: { description: 'Components that have moved to a different stage in their lifecycle should be imported from the relevant path.', recommended: 'recommended', }, messages: { refactor: '`{{name}}` has moved to a different stage in its lifecycle. Import it from `{{source}}` instead.', }, }, defaultOptions: [], create(context) { return mappings.reduce((visitors, config) => { const { from, to, specifiers } = config; return Object.assign(visitors, { [`ImportDeclaration:has(Literal[value="${from}"])`]: (node) => { node.specifiers.forEach((specifier) => { if (specifier.type !== 'ImportSpecifier') { return; } const importedName = specifier.imported.name; const localName = specifier.local.name; if (!specifiers.includes(importedName)) { return; } const importStatement = node.importKind === 'type' ? 'import type' : 'import'; const importSpecifier = importedName === localName ? importedName : `${importedName} as ${localName}`; context.report({ node: specifier, messageId: 'refactor', data: { name: importedName, source: to }, fix(fixer) { const fixes = []; if (node.specifiers.length === 1) { // Remove the import entirely if there's only one specifier fixes.push(fixer.remove(node)); } else { // ...otherwise, only remove the specifier fixes.push(fixer.replaceText(node, context.sourceCode .getText(node) .replace(importSpecifier, '') .replace(' ,', ''))); } // Insert the new import fixes.push(fixer.insertTextAfter(node, `${importStatement} { ${importSpecifier} } from '${to}';`)); return fixes; }, }); }); }, }); }, {}); }, });