|
| 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