installSpecificWidget function

Future<bool> installSpecificWidget(
  1. String projectPath,
  2. String widgetName, {
  3. bool force = false,
})

Implementation

Future<bool> installSpecificWidget(String projectPath, String widgetName,
    {bool force = false}) async {
  String normalizedSearch = widgetName.replaceAll('_', '').toLowerCase();

  if (normalizedSearch == 'assestwidget') {
    normalizedSearch = 'assetwidget';
  }

  String? matchedRelativePath;
  for (var key in widgetsTemplatesMap.keys) {
    final fileName = key.split('/').last;
    String normalizedKey =
        fileName.replaceAll('.dart', '').replaceAll('_', '').toLowerCase();
    String strippedKey =
        normalizedKey.replaceAll('common', '').replaceAll('custom', '');

    if (normalizedKey == normalizedSearch ||
        strippedKey == normalizedSearch ||
        normalizedKey.contains(normalizedSearch)) {
      matchedRelativePath = key;
      break;
    }
  }

  if (matchedRelativePath != null) {
    final projectName = getProjectName(projectPath);
    final Set<String> resolvedFiles = {};
    final Set<String> pluginsToAdd = {};

    void resolveAndWrite(String relativePath) {
      if (resolvedFiles.contains(relativePath)) return;
      final templateFunc = widgetsTemplatesMap[relativePath];
      if (templateFunc == null) return;

      resolvedFiles.add(relativePath);

      final content = templateFunc(projectName);
      final filePath = p.join(projectPath, 'lib', relativePath);
      safeCreateDir(File(filePath).parent.path);

      safeWriteFile(filePath, content,
          overwrite: force, projectPath: projectPath);

      final importRegex = RegExp(r"import\s+['" "]([^'" "]+)['" "]");
      final matches = importRegex.allMatches(content);

      for (final match in matches) {
        final importPath = match.group(1)!;

        if (importPath.startsWith('package:$projectName/')) {
          final relativeImportPath =
              importPath.replaceFirst('package:$projectName/', '');
          if (widgetsTemplatesMap.containsKey(relativeImportPath)) {
            resolveAndWrite(relativeImportPath);
          }
        } else if (!importPath.startsWith('package:') &&
            !importPath.startsWith('dart:')) {
          final dirPath = p.dirname(relativePath);
          final joinedPath =
              p.normalize(p.join(dirPath, importPath)).replaceAll(r'\', '/');
          if (widgetsTemplatesMap.containsKey(joinedPath)) {
            resolveAndWrite(joinedPath);
          }
        } else if (importPath.startsWith('package:')) {
          final pluginName =
              importPath.split('/')[0].replaceFirst('package:', '');
          if (pluginName != 'flutter' &&
              pluginName != 'flutter_enterprise_cli') {
            pluginsToAdd.add(pluginName);
          }
        }
      }
    }

    resolveAndWrite(matchedRelativePath);

    print(
        '✅ Successfully added $matchedRelativePath and ${resolvedFiles.length - 1} dependencies.');

    if (pluginsToAdd.isNotEmpty) {
      print('📦 Installing required external plugins...');
      final flutterCmd = Platform.isWindows ? 'flutter.bat' : 'flutter';

      final args = ['pub', 'add'];
      args.addAll(pluginsToAdd);

      await Process.run(
        flutterCmd,
        args,
        workingDirectory: projectPath,
        runInShell: true,
      );
      print(
          '✅ Required plugins ${pluginsToAdd.join(", ")} installed successfully.');
    }

    return true;
  }

  return false;
}