Skip to content

Commit cda443e

Browse files
chore(devex): Add types for getFromPackage and pfPackageMatcher helpers (#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
1 parent 3d190be commit cda443e

File tree

7 files changed

+113
-55
lines changed

7 files changed

+113
-55
lines changed

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
"test:v5:single": "pf-codemods --no-cache test/test.tsx",
1313
"test:v6:single": "yarn build && pf-codemods --v6 --no-cache packages/eslint-plugin-pf-codemods/src/rules/v6/*/*Input.tsx",
1414
"test:v6:single:output": "yarn build && pf-codemods --v6 --no-cache packages/eslint-plugin-pf-codemods/src/rules/v6/*/*Output.tsx",
15-
"test:koku": "pf-codemods --no-cache test/koku-ui",
16-
"test:console": "pf-codemods --no-cache test/console/frontend",
17-
"test:integreatly": "pf-codemods --no-cache test/tutorial-web-app",
18-
"test:packages": "yarn get:packages && node --unhandled-rejections=strict packages/pf-codemods/index.js --no-cache test/packages",
15+
"test:koku": "pf-codemods --v6 --no-cache test/koku-ui",
16+
"test:console": "pf-codemods --v6 --no-cache test/console/frontend",
17+
"test:integreatly": "pf-codemods --v6 --no-cache test/tutorial-web-app",
18+
"test:packages": "yarn get:packages && node --unhandled-rejections=strict packages/pf-codemods/index.js --v6 --no-cache test/packages",
1919
"test:classnames": "class-name-updater --no-cache test",
2020
"get:packages": "node getPackages.js",
2121
"generate": "yarn build:generators && plop",

packages/eslint-plugin-pf-codemods/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"typescript": ">=3.8.3"
2424
},
2525
"devDependencies": {
26-
"@types/eslint": "^8.56.0"
26+
"@types/eslint": "^8.56.0",
27+
"@types/estree-jsx": "^1.0.4"
2728
}
2829
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { Rule } from "eslint";
2+
import {
3+
ImportDeclaration,
4+
ModuleDeclaration,
5+
Statement,
6+
Directive,
7+
ExportNamedDeclaration,
8+
ImportSpecifier,
9+
ExportSpecifier,
10+
} from "estree-jsx";
11+
import { pfPackageMatches } from "./pfPackageMatches";
12+
13+
type Declarations = ImportDeclaration | ExportNamedDeclaration;
14+
type Specifiers = ImportSpecifier | ExportSpecifier;
15+
16+
function filterByPackageName(nodes: Declarations[], packageName: string) {
17+
return nodes.filter((node) => {
18+
const nodeValue = node?.source?.value;
19+
20+
if (typeof nodeValue !== "string") {
21+
return false;
22+
}
23+
if (packageName.startsWith("@patternfly")) {
24+
return pfPackageMatches(packageName, nodeValue);
25+
}
26+
return nodeValue === packageName;
27+
});
28+
}
29+
30+
function getSpecifiers<
31+
NodeType extends Declarations,
32+
SpecifierType extends Specifiers
33+
>(
34+
astBody: (ModuleDeclaration | Statement | Directive)[],
35+
nodeType: "ImportDeclaration" | "ExportNamedDeclaration",
36+
packageName: string
37+
): SpecifierType[] {
38+
const nodesOfSpecifiedType = astBody.filter(
39+
(node) => node?.type === nodeType
40+
) as NodeType[];
41+
const pfNodes = filterByPackageName(nodesOfSpecifiedType, packageName);
42+
const specifiers = pfNodes.map((node) => node.specifiers);
43+
44+
const specifierType =
45+
nodeType === "ImportDeclaration" ? "ImportSpecifier" : "ExportSpecifier";
46+
47+
const filteredSpecifiersByType = specifiers.filter((specifierArray) =>
48+
specifierArray.every((specifier) => specifier.type === specifierType)
49+
) as unknown as SpecifierType[];
50+
51+
return filteredSpecifiersByType.reduce(
52+
(acc, val) => acc.concat(val),
53+
[] as SpecifierType[]
54+
);
55+
}
56+
57+
export function getFromPackage(context: Rule.RuleContext, packageName: string) {
58+
const astBody = context.getSourceCode().ast.body;
59+
60+
const imports = getSpecifiers<ImportDeclaration, ImportSpecifier>(
61+
astBody,
62+
"ImportDeclaration",
63+
packageName
64+
);
65+
const exports = getSpecifiers<ExportNamedDeclaration, ExportSpecifier>(
66+
astBody,
67+
"ExportNamedDeclaration",
68+
packageName
69+
);
70+
71+
return { imports, exports };
72+
}

packages/eslint-plugin-pf-codemods/src/rules/helpers.js renamed to packages/eslint-plugin-pf-codemods/src/rules/helpers/helpers.js

Lines changed: 3 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import { getFromPackage } from "./getFromPackage";
2+
import { pfPackageMatches } from "./pfPackageMatches";
3+
14
const evk = require("eslint-visitor-keys");
25

36
export function moveSpecifiers(
@@ -286,56 +289,6 @@ export function moveSpecifiers(
286289
};
287290
}
288291

289-
export function pfPackageMatches(packageName, nodeSrc) {
290-
const parts = packageName.split("/");
291-
const regex = new RegExp(
292-
"^" +
293-
parts[0] +
294-
"/" +
295-
parts[1] +
296-
"(/dist/(esm|js))?" +
297-
(parts[2] ? "/" + parts[2] : "") +
298-
"(/(components|helpers)/.*)?$"
299-
);
300-
return regex.test(nodeSrc);
301-
}
302-
303-
/**
304-
*
305-
* @param context
306-
* @param {string} packageName
307-
* @param {string[]} specifierNames
308-
* @returns {{ imports, exports }} an object containing an array of imports and array of named exports
309-
*/
310-
export function getFromPackage(context, packageName, specifierNames = []) {
311-
const astBody = context.getSourceCode().ast.body;
312-
const getSpecifiers = (nodeType) =>
313-
astBody
314-
.filter((node) => node?.type === nodeType)
315-
.filter((node) => {
316-
if (packageName.startsWith("@patternfly")) {
317-
return pfPackageMatches(packageName, node?.source?.value);
318-
}
319-
return node?.source?.value === packageName;
320-
})
321-
.map((node) => node?.specifiers)
322-
.reduce((acc, val) => acc.concat(val), []);
323-
324-
const imports = getSpecifiers("ImportDeclaration");
325-
const exports = getSpecifiers("ExportNamedDeclaration");
326-
327-
return !specifierNames.length
328-
? { imports, exports }
329-
: {
330-
imports: imports.filter((s) =>
331-
specifierNames?.includes(s?.imported?.name)
332-
),
333-
exports: exports.filter((s) =>
334-
specifierNames?.includes(s?.local?.name)
335-
),
336-
};
337-
}
338-
339292
export function splitSpecifiers(declaration, specifiersToSplit) {
340293
let keepSpecifiers = [];
341294

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './helpers';
2+
export * from './pfPackageMatches';
3+
export * from './getFromPackage';
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { ImportDeclaration } from "estree-jsx";
2+
3+
export function pfPackageMatches(
4+
packageName: string,
5+
nodeSrc: ImportDeclaration["source"]["value"]
6+
) {
7+
if (typeof nodeSrc !== "string") {
8+
return false;
9+
}
10+
11+
const parts = packageName.split("/");
12+
const regex = new RegExp(
13+
"^" +
14+
parts[0] +
15+
"/" +
16+
parts[1] +
17+
"(/dist/(esm|js))?" +
18+
(parts[2] ? "/" + parts[2] : "") +
19+
"(/(components|helpers)/.*)?$"
20+
);
21+
return regex.test(nodeSrc);
22+
}

yarn.lock

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,13 @@
10561056
"@types/estree" "*"
10571057
"@types/json-schema" "*"
10581058

1059+
"@types/estree-jsx@^1.0.4":
1060+
version "1.0.4"
1061+
resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.4.tgz#8d34b43444887dde8a73af530f772f23e1d3287c"
1062+
integrity sha512-5idy3hvI9lAMqsyilBM+N+boaCf1MgoefbDxN6KEO5aK17TOHwFAYT9sjxzeKAiIWRUBgLxmZ9mPcnzZXtTcRQ==
1063+
dependencies:
1064+
"@types/estree" "*"
1065+
10591066
"@types/estree@*":
10601067
version "1.0.5"
10611068
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"

0 commit comments

Comments
 (0)