Skip to content

Commit

Permalink
chore(devex): Add types for getFromPackage and pfPackageMatcher helpe…
Browse files Browse the repository at this point in the history
…rs (#577)

* chore(devex): Add types for getFromPackage and pfPackageMatcher helpers

* chore(helpers): add helper imports to helper.js file

* chore(helpers): Refactor to use .getSourceCode() instead of .sourceCode
  • Loading branch information
wise-king-sullyman authored Feb 21, 2024
1 parent 3d190be commit cda443e
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 55 deletions.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
"test:v5:single": "pf-codemods --no-cache test/test.tsx",
"test:v6:single": "yarn build && pf-codemods --v6 --no-cache packages/eslint-plugin-pf-codemods/src/rules/v6/*/*Input.tsx",
"test:v6:single:output": "yarn build && pf-codemods --v6 --no-cache packages/eslint-plugin-pf-codemods/src/rules/v6/*/*Output.tsx",
"test:koku": "pf-codemods --no-cache test/koku-ui",
"test:console": "pf-codemods --no-cache test/console/frontend",
"test:integreatly": "pf-codemods --no-cache test/tutorial-web-app",
"test:packages": "yarn get:packages && node --unhandled-rejections=strict packages/pf-codemods/index.js --no-cache test/packages",
"test:koku": "pf-codemods --v6 --no-cache test/koku-ui",
"test:console": "pf-codemods --v6 --no-cache test/console/frontend",
"test:integreatly": "pf-codemods --v6 --no-cache test/tutorial-web-app",
"test:packages": "yarn get:packages && node --unhandled-rejections=strict packages/pf-codemods/index.js --v6 --no-cache test/packages",
"test:classnames": "class-name-updater --no-cache test",
"get:packages": "node getPackages.js",
"generate": "yarn build:generators && plop",
Expand Down
3 changes: 2 additions & 1 deletion packages/eslint-plugin-pf-codemods/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"typescript": ">=3.8.3"
},
"devDependencies": {
"@types/eslint": "^8.56.0"
"@types/eslint": "^8.56.0",
"@types/estree-jsx": "^1.0.4"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Rule } from "eslint";
import {
ImportDeclaration,
ModuleDeclaration,
Statement,
Directive,
ExportNamedDeclaration,
ImportSpecifier,
ExportSpecifier,
} from "estree-jsx";
import { pfPackageMatches } from "./pfPackageMatches";

type Declarations = ImportDeclaration | ExportNamedDeclaration;
type Specifiers = ImportSpecifier | ExportSpecifier;

function filterByPackageName(nodes: Declarations[], packageName: string) {
return nodes.filter((node) => {
const nodeValue = node?.source?.value;

if (typeof nodeValue !== "string") {
return false;
}
if (packageName.startsWith("@patternfly")) {
return pfPackageMatches(packageName, nodeValue);
}
return nodeValue === packageName;
});
}

function getSpecifiers<
NodeType extends Declarations,
SpecifierType extends Specifiers
>(
astBody: (ModuleDeclaration | Statement | Directive)[],
nodeType: "ImportDeclaration" | "ExportNamedDeclaration",
packageName: string
): SpecifierType[] {
const nodesOfSpecifiedType = astBody.filter(
(node) => node?.type === nodeType
) as NodeType[];
const pfNodes = filterByPackageName(nodesOfSpecifiedType, packageName);
const specifiers = pfNodes.map((node) => node.specifiers);

const specifierType =
nodeType === "ImportDeclaration" ? "ImportSpecifier" : "ExportSpecifier";

const filteredSpecifiersByType = specifiers.filter((specifierArray) =>
specifierArray.every((specifier) => specifier.type === specifierType)
) as unknown as SpecifierType[];

return filteredSpecifiersByType.reduce(
(acc, val) => acc.concat(val),
[] as SpecifierType[]
);
}

export function getFromPackage(context: Rule.RuleContext, packageName: string) {
const astBody = context.getSourceCode().ast.body;

const imports = getSpecifiers<ImportDeclaration, ImportSpecifier>(
astBody,
"ImportDeclaration",
packageName
);
const exports = getSpecifiers<ExportNamedDeclaration, ExportSpecifier>(
astBody,
"ExportNamedDeclaration",
packageName
);

return { imports, exports };
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { getFromPackage } from "./getFromPackage";
import { pfPackageMatches } from "./pfPackageMatches";

const evk = require("eslint-visitor-keys");

export function moveSpecifiers(
Expand Down Expand Up @@ -286,56 +289,6 @@ export function moveSpecifiers(
};
}

export function pfPackageMatches(packageName, nodeSrc) {
const parts = packageName.split("/");
const regex = new RegExp(
"^" +
parts[0] +
"/" +
parts[1] +
"(/dist/(esm|js))?" +
(parts[2] ? "/" + parts[2] : "") +
"(/(components|helpers)/.*)?$"
);
return regex.test(nodeSrc);
}

/**
*
* @param context
* @param {string} packageName
* @param {string[]} specifierNames
* @returns {{ imports, exports }} an object containing an array of imports and array of named exports
*/
export function getFromPackage(context, packageName, specifierNames = []) {
const astBody = context.getSourceCode().ast.body;
const getSpecifiers = (nodeType) =>
astBody
.filter((node) => node?.type === nodeType)
.filter((node) => {
if (packageName.startsWith("@patternfly")) {
return pfPackageMatches(packageName, node?.source?.value);
}
return node?.source?.value === packageName;
})
.map((node) => node?.specifiers)
.reduce((acc, val) => acc.concat(val), []);

const imports = getSpecifiers("ImportDeclaration");
const exports = getSpecifiers("ExportNamedDeclaration");

return !specifierNames.length
? { imports, exports }
: {
imports: imports.filter((s) =>
specifierNames?.includes(s?.imported?.name)
),
exports: exports.filter((s) =>
specifierNames?.includes(s?.local?.name)
),
};
}

export function splitSpecifiers(declaration, specifiersToSplit) {
let keepSpecifiers = [];

Expand Down
3 changes: 3 additions & 0 deletions packages/eslint-plugin-pf-codemods/src/rules/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './helpers';
export * from './pfPackageMatches';
export * from './getFromPackage';
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ImportDeclaration } from "estree-jsx";

export function pfPackageMatches(
packageName: string,
nodeSrc: ImportDeclaration["source"]["value"]
) {
if (typeof nodeSrc !== "string") {
return false;
}

const parts = packageName.split("/");
const regex = new RegExp(
"^" +
parts[0] +
"/" +
parts[1] +
"(/dist/(esm|js))?" +
(parts[2] ? "/" + parts[2] : "") +
"(/(components|helpers)/.*)?$"
);
return regex.test(nodeSrc);
}
7 changes: 7 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,13 @@
"@types/estree" "*"
"@types/json-schema" "*"

"@types/estree-jsx@^1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.4.tgz#8d34b43444887dde8a73af530f772f23e1d3287c"
integrity sha512-5idy3hvI9lAMqsyilBM+N+boaCf1MgoefbDxN6KEO5aK17TOHwFAYT9sjxzeKAiIWRUBgLxmZ9mPcnzZXtTcRQ==
dependencies:
"@types/estree" "*"

"@types/estree@*":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
Expand Down

0 comments on commit cda443e

Please sign in to comment.