diff --git a/packages/eslint-plugin-pf-codemods/src/rules/helpers/isEnumValue.ts b/packages/eslint-plugin-pf-codemods/src/rules/helpers/isEnumValue.ts index 398b07920..f5cc0fad8 100644 --- a/packages/eslint-plugin-pf-codemods/src/rules/helpers/isEnumValue.ts +++ b/packages/eslint-plugin-pf-codemods/src/rules/helpers/isEnumValue.ts @@ -11,8 +11,8 @@ export function isEnumValue( propertyName: string | string[] ) { if ( - enumExpression.object?.type === "Identifier" && - enumExpression.object.name === enumName + enumExpression?.object?.type === "Identifier" && + enumExpression?.object?.name === enumName ) { const nameMatches = (name: string) => propertyNameMatches( diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/buttonMoveIconsIconProp/button-moveIcons-icon-prop.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/buttonMoveIconsIconProp/button-moveIcons-icon-prop.ts index bb9c9d4ba..0cd94bc5b 100644 --- a/packages/eslint-plugin-pf-codemods/src/rules/v6/buttonMoveIconsIconProp/button-moveIcons-icon-prop.ts +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/buttonMoveIconsIconProp/button-moveIcons-icon-prop.ts @@ -1,5 +1,5 @@ import { Rule } from "eslint"; -import { JSXElement, JSXFragment } from "estree-jsx"; +import { JSXElement, JSXFragment, MemberExpression } from "estree-jsx"; import { childrenIsEmpty, getFromPackage, @@ -10,6 +10,8 @@ import { getChildJSXElementByName, isReactIcon, makeJSXElementSelfClosing, + propertyNameMatches, + isEnumValue, } from "../../helpers"; // https://github.com/patternfly/patternfly-react/pull/10663 @@ -47,11 +49,16 @@ module.exports = { variantProp?.value ); + const variantValueAsEnum = variantValue as MemberExpression; + const isEnumValuePlain = - buttonVariantEnumImport && - variantValue?.object?.name === - buttonVariantEnumImport.local.name && - variantValue?.property.name === "plain"; + !!buttonVariantEnumImport && + isEnumValue( + context, + variantValueAsEnum, + buttonVariantEnumImport.local.name, + "plain" + ); const isPlain = variantValue === "plain" || isEnumValuePlain; diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/cardUpdatedClickableMarkup/card-updated-clickable-markup.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/cardUpdatedClickableMarkup/card-updated-clickable-markup.ts index 5940c269f..29972658d 100644 --- a/packages/eslint-plugin-pf-codemods/src/rules/v6/cardUpdatedClickableMarkup/card-updated-clickable-markup.ts +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/cardUpdatedClickableMarkup/card-updated-clickable-markup.ts @@ -1,7 +1,6 @@ import { Rule } from "eslint"; -import { JSXElement, Property, Literal } from "estree-jsx"; +import { JSXElement, ObjectExpression, Property } from "estree-jsx"; import { - getAllImportsFromPackage, getFromPackage, checkMatchingJSXOpeningElement, getAttribute, @@ -54,19 +53,23 @@ module.exports = { const selectableActionsValue = getAttributeValue( context, selectableActionsProp.value - ); + ) as ObjectExpression["properties"]; if (!selectableActionsValue) { return; } + const selectableActionsProperties = selectableActionsValue.filter( + (val) => val.type === "Property" + ) as Property[]; + const nameProperty = getObjectProperty( context, - selectableActionsValue, + selectableActionsProperties, "name" ); const idProperty = getObjectProperty( context, - selectableActionsValue, + selectableActionsProperties, "selectableActionId" ); @@ -92,7 +95,7 @@ module.exports = { return []; } const propertiesToKeep = removePropertiesFromObjectExpression( - selectableActionsValue, + selectableActionsProperties, validPropertiesToRemove ); const replacementProperties = propertiesToKeep diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/colorPropsReplacedColors/colorProps-replaced-colors.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/colorPropsReplacedColors/colorProps-replaced-colors.ts index faa9e14f0..b5753cbbb 100644 --- a/packages/eslint-plugin-pf-codemods/src/rules/v6/colorPropsReplacedColors/colorProps-replaced-colors.ts +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/colorPropsReplacedColors/colorProps-replaced-colors.ts @@ -32,7 +32,10 @@ module.exports = { return; } - const colorValue = getAttributeValue(context, colorProp.value); + const colorValue = getAttributeValue( + context, + colorProp.value + ) as string; if (Object.keys(replacementMap).includes(colorValue)) { const newColorValue = replacementMap[colorValue]; const message = `The \`color\` prop on ${node.name.name} has been updated to replace "${colorValue}" with "${newColorValue}".`; diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/componentGroupsUnavailableContentBodyTextPropsUpdate/component-groups-unavailableContent-bodyText-props-update.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/componentGroupsUnavailableContentBodyTextPropsUpdate/component-groups-unavailableContent-bodyText-props-update.ts index 46d00c077..e0aa0abb7 100644 --- a/packages/eslint-plugin-pf-codemods/src/rules/v6/componentGroupsUnavailableContentBodyTextPropsUpdate/component-groups-unavailableContent-bodyText-props-update.ts +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/componentGroupsUnavailableContentBodyTextPropsUpdate/component-groups-unavailableContent-bodyText-props-update.ts @@ -28,9 +28,11 @@ module.exports = { node, "statusPageLinkText" ); - const statusPageLinkTextString: string = - getAttributeValue(context, statusPageLinkTextProp?.value) ?? - "status page"; + const statusPageLinkTextString = + (getAttributeValue( + context, + statusPageLinkTextProp?.value + ) as string) ?? "status page"; if (statusPageLinkTextProp && statusPageLinkTextString.length) { const firstChar = statusPageLinkTextString.charAt(0); diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContent-replace-noBackground-colorVariant.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContent-replace-noBackground-colorVariant.ts index 7cca10765..4c0a4c595 100644 --- a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContent-replace-noBackground-colorVariant.ts +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContent-replace-noBackground-colorVariant.ts @@ -1,6 +1,12 @@ import { Rule } from "eslint"; -import { JSXOpeningElement } from "estree-jsx"; -import { getFromPackage, getAttribute, getAttributeValue } from "../../helpers"; +import { JSXOpeningElement, MemberExpression } from "estree-jsx"; +import { + getFromPackage, + getAttribute, + getAttributeValue, + isEnumValue, + getEnumPropertyName, +} from "../../helpers"; // https://github.com/patternfly/patternfly-react/pull/10211 module.exports = { @@ -38,18 +44,30 @@ module.exports = { context, colorVariantProp.value ); - const drawerColorVariantLocalName = - drawerColorVariantEnumImport && - drawerColorVariantEnumImport.local.name; + + const colorVariantValueAsEnum = + colorVariantValue as MemberExpression; + const hasPatternFlyEnum = - colorVariantValue && - colorVariantValue.object && - colorVariantValue.object.name === drawerColorVariantLocalName; + drawerColorVariantEnumImport && + colorVariantValueAsEnum && + colorVariantValueAsEnum.object && + context + .getSourceCode() + .getText(colorVariantValueAsEnum.object) === + drawerColorVariantEnumImport.local.name; + + const isNoBackgroundEnum = + !!drawerColorVariantEnumImport && + isEnumValue( + context, + colorVariantValueAsEnum, + drawerColorVariantEnumImport.local.name, + "noBackground" + ); + const hasNoBackgroundValue = - colorVariantValue && colorVariantValue.property - ? hasPatternFlyEnum && - colorVariantValue.property.name === "noBackground" - : colorVariantValue === "no-background"; + colorVariantValue === "no-background" || isNoBackgroundEnum; if (!hasPatternFlyEnum && !hasNoBackgroundValue) { return; @@ -68,15 +86,19 @@ module.exports = { } if (!hasNoBackgroundValue && hasPatternFlyEnum) { - const enumPropertyName = colorVariantValue.property.name; - fixes.push( - fixer.replaceText( - colorVariantProp, - validDrawerContentValues.includes(enumPropertyName) - ? `colorVariant="${colorVariantValue.property.name}"` - : "" - ) + const enumPropertyName = getEnumPropertyName( + context, + colorVariantValueAsEnum ); + enumPropertyName && + fixes.push( + fixer.replaceText( + colorVariantProp, + validDrawerContentValues.includes(enumPropertyName) + ? `colorVariant="${enumPropertyName}"` + : "" + ) + ); } return fixes; }, diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/pageSectionRemoveNavType/pageSection-remove-nav-type.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/pageSectionRemoveNavType/pageSection-remove-nav-type.ts index d3b588abc..c9e315fa5 100644 --- a/packages/eslint-plugin-pf-codemods/src/rules/v6/pageSectionRemoveNavType/pageSection-remove-nav-type.ts +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/pageSectionRemoveNavType/pageSection-remove-nav-type.ts @@ -1,6 +1,11 @@ import { Rule } from "eslint"; -import { JSXOpeningElement } from "estree-jsx"; -import { getFromPackage, getAttribute, getAttributeValue } from "../../helpers"; +import { JSXOpeningElement, MemberExpression } from "estree-jsx"; +import { + getFromPackage, + getAttribute, + getAttributeValue, + isEnumValue, +} from "../../helpers"; // https://github.com/patternfly/patternfly-react/pull/10650 module.exports = { @@ -29,10 +34,17 @@ module.exports = { } const typeValue = getAttributeValue(context, typeProp.value); + const typeValueAsEnum = typeValue as MemberExpression; + const isEnumValueNav = pageSectionTypeEnum && - typeValue.object?.name === pageSectionTypeEnum.local.name && - typeValue.property.name === "nav"; + isEnumValue( + context, + typeValueAsEnum, + pageSectionTypeEnum.local.name, + "nav" + ); + if (typeValue !== "nav" && !isEnumValueNav) { return; } diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/pageSectionUpdateVariantValues/pageSection-update-variant-values.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/pageSectionUpdateVariantValues/pageSection-update-variant-values.ts index 108d0b26c..f86a5122d 100644 --- a/packages/eslint-plugin-pf-codemods/src/rules/v6/pageSectionUpdateVariantValues/pageSection-update-variant-values.ts +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/pageSectionUpdateVariantValues/pageSection-update-variant-values.ts @@ -1,6 +1,12 @@ -import { getFromPackage, getAttribute, getAttributeValue } from "../../helpers"; +import { + getFromPackage, + getAttribute, + getAttributeValue, + isEnumValue, + attributeValueIsString, +} from "../../helpers"; import { Rule } from "eslint"; -import { JSXOpeningElement } from "estree-jsx"; +import { JSXOpeningElement, MemberExpression } from "estree-jsx"; // https://github.com/patternfly/patternfly-react/pull/9774 // https://github.com/patternfly/patternfly-react/pull/9848 @@ -34,21 +40,33 @@ module.exports = { context, variantProp.value ); - const pageSectionVariantLocalName = - pageSectionVariantImport && pageSectionVariantImport.local.name; + const variantValueAsEnum = variantValue as MemberExpression; + const hasPatternFlyEnum = - variantValue?.object && - variantValue.object.name === pageSectionVariantLocalName; - const variantValueIsLiteral = - variantProp.value.type === "Literal" || - (variantProp.value.type === "JSXExpressionContainer" && - variantProp.value.expression.type === "Literal"); - if (!variantValueIsLiteral && !hasPatternFlyEnum) { + pageSectionVariantImport && + variantValueAsEnum?.object && + context.getSourceCode().getText(variantValueAsEnum.object) === + pageSectionVariantImport.local.name; + + if ( + !attributeValueIsString(variantProp.value) && + !hasPatternFlyEnum + ) { return; } - const hasValidValue = variantValue?.property - ? validValues.includes(variantValue.property.name) - : validValues.includes(variantValue); + + const isValidEnumValue = + pageSectionVariantImport && + isEnumValue( + context, + variantValueAsEnum, + pageSectionVariantImport.local.name, + validValues + ); + + const hasValidValue = + isValidEnumValue || + validValues.includes(variantValue as string); if (!hasValidValue) { context.report({ diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/toolbarGroupUpdatedIconButtonGroupVariant/toolbarGroup-updated-variant.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/toolbarGroupUpdatedIconButtonGroupVariant/toolbarGroup-updated-variant.ts index 5129fac90..e8daa9bcf 100644 --- a/packages/eslint-plugin-pf-codemods/src/rules/v6/toolbarGroupUpdatedIconButtonGroupVariant/toolbarGroup-updated-variant.ts +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/toolbarGroupUpdatedIconButtonGroupVariant/toolbarGroup-updated-variant.ts @@ -1,6 +1,12 @@ import { Rule } from "eslint"; -import { JSXOpeningElement } from "estree-jsx"; -import { getFromPackage, getAttribute, getAttributeValue } from "../../helpers"; +import { JSXOpeningElement, MemberExpression } from "estree-jsx"; +import { + getFromPackage, + getAttribute, + getAttributeValue, + getEnumPropertyName, + isEnumValue, +} from "../../helpers"; // https://github.com/patternfly/patternfly-react/pull/10674 module.exports = { @@ -20,6 +26,7 @@ module.exports = { "icon-button-group": "action-group-plain", }; const oldVariantNames = Object.keys(renames); + type OldVariantType = "button-group" | "icon-button-group"; return !componentImports.length ? {} @@ -38,24 +45,37 @@ module.exports = { } const variantValue = getAttributeValue(context, variant.value); + const variantValueAsEnum = variantValue as MemberExpression; + const isEnumToRename = variantEnumImport && - variantValue.object?.name === variantEnumImport.local.name && - oldVariantNames.includes(variantValue.property.value); + isEnumValue( + context, + variantValueAsEnum, + variantEnumImport.local.name, + oldVariantNames + ); - if (!oldVariantNames.includes(variantValue) && !isEnumToRename) { + if ( + !oldVariantNames.includes(variantValue as string) && + !isEnumToRename + ) { return; } - const variantToRename: "button-group" | "icon-button-group" = - variantValue.property?.value ?? variantValue; + const variantToRename = isEnumToRename + ? (getEnumPropertyName( + context, + variantValueAsEnum + ) as OldVariantType) + : (variantValue as OldVariantType); context.report({ node, message: `The \`${variantToRename}\` variant of ${applicableComponent.imported.name} has been renamed to \`${renames[variantToRename]}\`.`, fix(fixer) { return fixer.replaceText( - isEnumToRename ? variantValue.property : variant, + isEnumToRename ? variantValueAsEnum.property : variant, isEnumToRename ? `"${renames[variantToRename]}"` : `variant="${renames[variantToRename]}"` diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/toolbarItemVariantPropUpdates/toolbarItem-variant-prop-updates.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/toolbarItemVariantPropUpdates/toolbarItem-variant-prop-updates.ts index ccd82f0c8..f141cb72d 100644 --- a/packages/eslint-plugin-pf-codemods/src/rules/v6/toolbarItemVariantPropUpdates/toolbarItem-variant-prop-updates.ts +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/toolbarItemVariantPropUpdates/toolbarItem-variant-prop-updates.ts @@ -10,6 +10,8 @@ import { getAttribute, getAttributeValue, attributeValueIsString, + getEnumPropertyName, + isEnumValue, } from "../../helpers"; // https://github.com/patternfly/patternfly-react/pull/10649 @@ -76,14 +78,26 @@ module.exports = { variant.value ); + const isEnumToRemove = + enumImport && + isEnumValue( + context, + variantValue as MemberExpression, + enumImport.local.name, + variantsToRemove + ); + if ( (variantValueIsLiteral && - variantsToRemove.includes(variantValue)) || - (nodeIsEnum(variantValue) && - variantsToRemove.includes(variantValue.property.value)) + variantsToRemove.includes(variantValue as string)) || + isEnumToRemove ) { - const variantToRemove = - variantValue.property?.value ?? variantValue; + const variantToRemove = isEnumToRemove + ? getEnumPropertyName( + context, + variantValue as MemberExpression + ) + : variantValue; context.report({ node, diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/toolbarReplacedSpacerSpaceItems/toolbar-replaced-spacer-spaceItems.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/toolbarReplacedSpacerSpaceItems/toolbar-replaced-spacer-spaceItems.ts index f31838469..960f017bd 100644 --- a/packages/eslint-plugin-pf-codemods/src/rules/v6/toolbarReplacedSpacerSpaceItems/toolbar-replaced-spacer-spaceItems.ts +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/toolbarReplacedSpacerSpaceItems/toolbar-replaced-spacer-spaceItems.ts @@ -1,5 +1,5 @@ import { Rule } from "eslint"; -import { JSXOpeningElement } from "estree-jsx"; +import { JSXOpeningElement, ObjectExpression } from "estree-jsx"; import { Property } from "estree-jsx"; import { getFromPackage, getAttribute, getAttributeValue } from "../../helpers"; @@ -35,7 +35,11 @@ module.exports = { spacerProp ? " Additionally, the" : "The" } spaceItems property has been removed from ${node.name.name}.`; const spacerVal = - spacerProp && getAttributeValue(context, spacerProp.value); + spacerProp && + (getAttributeValue( + context, + spacerProp.value + ) as ObjectExpression["properties"]); context.report({ node, @@ -47,7 +51,11 @@ module.exports = { if (spacerProp) { spacerVal && - spacerVal.forEach((val: Property) => { + spacerVal.forEach((val) => { + if (val.type !== "Property") { + return; + } + const newValue = val.value?.type === "Literal" && (val.value.value as string).replace("spacer", "gap"); diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/toolbarUpdateAlignValues/toolbar-update-align-values.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/toolbarUpdateAlignValues/toolbar-update-align-values.ts index 03b531821..8d39365ce 100644 --- a/packages/eslint-plugin-pf-codemods/src/rules/v6/toolbarUpdateAlignValues/toolbar-update-align-values.ts +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/toolbarUpdateAlignValues/toolbar-update-align-values.ts @@ -1,5 +1,10 @@ import { Rule } from "eslint"; -import { JSXOpeningElement, Property } from "estree-jsx"; +import { + Identifier, + JSXOpeningElement, + ObjectExpression, + Property, +} from "estree-jsx"; import { getFromPackage, getAttribute, getAttributeValue } from "../../helpers"; const componentsPropMap: { [key: string]: string } = { @@ -47,15 +52,20 @@ module.exports = { return; } - const attributeValue = getAttributeValue( - context, - attribute.value - ); + const attributeValueProperties = ( + getAttributeValue( + context, + attribute.value + ) as ObjectExpression["properties"] + ).filter((prop) => prop.type === "Property") as Property[]; if ( - attributeValue.every( - (property: Property) => - property.value.type === "Literal" && - !oldPropValues.includes(property.value.value as string) + attributeValueProperties.every( + (property) => + (property.value.type === "Literal" && + !oldPropValues.includes( + property.value.value as string + )) || + property.value.type !== "Literal" ) ) { return; @@ -67,18 +77,22 @@ module.exports = { fix(fixer) { const fixes = []; - for (const property of attributeValue) { - if (oldPropValues.includes(property.value.value)) { + for (const property of attributeValueProperties) { + if (property.value.type !== "Literal") { + continue; + } + + const propertyValueString = property.value.value as string; + + if (oldPropValues.includes(propertyValueString)) { const propertyKeyValue = property.key.type === "Literal" ? `"${property.key.value}"` - : property.key.name; + : (property.key as Identifier).name; fixes.push( fixer.replaceText( property, - `${propertyKeyValue}: "${ - newPropValueMap[property.value.value] - }"` + `${propertyKeyValue}: "${newPropValueMap[propertyValueString]}"` ) ); }