refresh-project-import.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /**
  2. * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
  3. * SPDX-License-Identifier: MIT
  4. */
  5. import path from 'path';
  6. import chalk from 'chalk';
  7. import { traverseRecursiveTsFiles } from '../utils/ts-file';
  8. import { ImportDeclaration, NamedImport } from '../utils/import';
  9. import { SyncMaterialContext } from './types';
  10. import { Material } from './material';
  11. export function executeRefreshProjectImport(context: SyncMaterialContext) {
  12. const { selectedMaterials, project, targetFormMaterialRoot } = context;
  13. const exportName2Material = new Map<string, Material>();
  14. const targetModule = `@/${path.relative(project.srcPath, targetFormMaterialRoot)}`;
  15. for (const material of selectedMaterials) {
  16. if (!material.indexFile) {
  17. console.warn(`Material ${material.name} not found`);
  18. return;
  19. }
  20. console.log(`👀 The exports of ${material.name} is ${material.allExportNames.join(',')}`);
  21. material.allExportNames.forEach((exportName) => {
  22. exportName2Material.set(exportName, material);
  23. });
  24. }
  25. for (const tsFile of traverseRecursiveTsFiles(project.srcPath)) {
  26. for (const importDeclaration of tsFile.imports) {
  27. if (importDeclaration.source.startsWith('@flowgram.ai/form-materials')) {
  28. // Import Module and its related named Imported
  29. const restImports: NamedImport[] = [];
  30. const importMap: Record<string, NamedImport[]> = {};
  31. if (!importDeclaration.namedImports) {
  32. continue;
  33. }
  34. for (const nameImport of importDeclaration.namedImports) {
  35. const material = exportName2Material.get(nameImport.imported);
  36. if (material) {
  37. const importModule = `${targetModule}/${material.fullName}`;
  38. importMap[importModule] = importMap[importModule] || [];
  39. importMap[importModule].push(nameImport);
  40. } else {
  41. restImports.push(nameImport);
  42. }
  43. }
  44. if (Object.keys(importMap).length === 0) {
  45. continue;
  46. }
  47. const nextImports: ImportDeclaration[] = Object.entries(importMap).map(
  48. ([importModule, namedImports]) => ({
  49. ...importDeclaration,
  50. namedImports,
  51. source: importModule,
  52. })
  53. );
  54. if (restImports?.length) {
  55. nextImports.unshift({
  56. ...importDeclaration,
  57. namedImports: restImports,
  58. });
  59. }
  60. tsFile.replaceImport([importDeclaration], nextImports);
  61. console.log(chalk.green(`🔄 Refresh Imports In: ${tsFile.path}`));
  62. console.log(
  63. `From:\n${importDeclaration.statement}\nTo:\n${nextImports
  64. .map((item) => item.statement)
  65. .join('\n')}`
  66. );
  67. }
  68. }
  69. }
  70. }