Skip to content

Commit 41c5df4

Browse files
committed
wcr codemod
1 parent ae03e24 commit 41c5df4

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed

packages/cli/src/scripts/codemod/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import childProcess from 'node:child_process';
22
import path from 'node:path';
33
import { fileURLToPath } from 'node:url';
44

5-
const SUPPORTED_TRANSFORMERS = ['v2'];
5+
const SUPPORTED_TRANSFORMERS = ['v2', 'export-maps'];
66

77
const __filename = fileURLToPath(import.meta.url);
88
const __dirname = path.dirname(__filename);
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/* eslint-disable @typescript-eslint/no-require-imports, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call */
2+
3+
import fs from 'fs';
4+
import path from 'path';
5+
import type { API, FileInfo, JSCodeshift, Collection } from 'jscodeshift';
6+
7+
const packageName = '@ui5/webcomponents-react';
8+
const libraryPath = require.resolve('@ui5/webcomponents-react/package.json');
9+
const enumsDir = path.join(path.dirname(libraryPath), 'dist', 'enums');
10+
11+
// build enum names dynamically from dist/enums filenames
12+
let enumNames: Set<string> = new Set();
13+
14+
try {
15+
enumNames = new Set(
16+
fs
17+
.readdirSync(enumsDir)
18+
.filter(
19+
(file) =>
20+
(file.endsWith('.js') || file.endsWith('.ts')) && !file.endsWith('.d.ts') && !file.startsWith('index'),
21+
)
22+
.map((file) => path.basename(file, path.extname(file))),
23+
);
24+
// console.log('Loaded enums:', Array.from(enumNames));
25+
} catch (e) {
26+
console.warn(`⚠️ Could not read enums directory at ${enumsDir}. Skipping enum detection.`, e);
27+
}
28+
29+
export default function transform(file: FileInfo, api: API): string | undefined {
30+
const j: JSCodeshift = api.jscodeshift;
31+
const root: Collection = j(file.source);
32+
33+
let isDirty = false;
34+
35+
root.find(j.ImportDeclaration, { source: { value: packageName } }).forEach((importPath) => {
36+
const specifiers = importPath.node.specifiers || [];
37+
38+
specifiers.forEach((spec) => {
39+
if (spec.type !== 'ImportSpecifier') return;
40+
41+
const importedName = spec.imported.name as string;
42+
const localName = spec.local ? spec.local.name : importedName;
43+
44+
// target component
45+
let componentName = importedName;
46+
if (importPath.node.importKind === 'type') {
47+
if (importedName.endsWith('PropTypes')) {
48+
componentName = importedName.replace(/PropTypes$/, '');
49+
} else if (importedName.endsWith('DomRef')) {
50+
componentName = importedName.replace(/DomRef$/, '');
51+
}
52+
}
53+
54+
// import path
55+
const newSource =
56+
importPath.node.importKind === 'type'
57+
? `${packageName}/${componentName}` // type imports
58+
: enumNames.has(importedName)
59+
? `${packageName}/enums/${importedName}` // enums
60+
: `${packageName}/${importedName}`; // regular component
61+
62+
const newImport = j.importDeclaration(
63+
//todo: as string
64+
[j.importSpecifier(j.identifier(importedName), j.identifier(localName as string))],
65+
j.literal(newSource),
66+
);
67+
68+
newImport.importKind = importPath.node.importKind;
69+
70+
j(importPath).insertBefore(newImport);
71+
isDirty = true;
72+
});
73+
74+
j(importPath).remove();
75+
});
76+
77+
return isDirty ? root.toSource({ quote: 'single' }) : undefined;
78+
}

0 commit comments

Comments
 (0)