generateModelClass function

bool generateModelClass(
  1. String srcDir,
  2. String distDir,
  3. String tag, {
  4. required bool nullable,
})

Implementation

bool generateModelClass(
  String srcDir,
  String distDir,
  String tag, {
  required bool nullable,
}) {
  const metaTag = "@meta";
  if (srcDir.endsWith("/")) srcDir = srcDir.substring(0, srcDir.length - 1);
  if (distDir.endsWith("/")) distDir = distDir.substring(0, distDir.length - 1);

  final src = Directory(srcDir);
  final fileList = src.listSync(recursive: true);
  String indexFile = "";
  if (fileList.isEmpty) return false;
  if (!Directory(distDir).existsSync()) {
    Directory(distDir).createSync(recursive: true);
  }

  File file;

  fileList.forEach((f) {
    if (FileSystemEntity.isFileSync(f.path)) {
      file = File(f.path);
      final paths = path.basename(f.path).split(".");
      final String fileName = paths.first;
      if (paths.last.toLowerCase() != "json" || fileName.startsWith("_"))
        return;

      final dartFilePath = f.path
          .replaceFirst(srcDir, distDir)
          .replaceFirst(RegExp('.json', caseSensitive: false), ".dart");

      final map = json.decode(file.readAsStringSync()) as Map<String, dynamic>;

      // To ensure that import statements are not repeated,
      // we use Set to save import statements
      final importSet = Set<String>();

      //Create a case-insensitive Map for the meta data of Json file
      final meta = LinkedHashMap<String, dynamic>(
        equals: (a, b) => a.toLowerCase().trim() == b.toLowerCase().trim(),
        hashCode: (k) => k.toLowerCase().hashCode,
      );

      // Get the meta data of Json file
      if (map[metaTag] != null) {
        meta.addAll(map[metaTag] as Map<String, dynamic>);
        map.remove(metaTag);
      }

      //generated class name
      String? className = meta['className'] as String?;
      if (className == null || className.isEmpty) {
        className = upperChar(fileName);
      }

      //set ignore
      final bool ignore = (meta['ignore'] ?? false) as bool;
      if (ignore) {
        print('skip: ${f.path}');
        indexFile = exportIndexFile(dartFilePath, distDir, indexFile);
        return;
      }

      //handle imports
      final List imports = (meta['import'] ?? []) as List;
      imports.forEach((e) => importSet.add("import '$e'"));

      //set nullable
      final bool _nullable = (meta['nullable'] ?? nullable) as bool;

      // comments for Json fields
      final comments = meta['comments'] ?? {};

      // Handle fields in Json file
      final StringBuffer fields = StringBuffer();
      map.forEach((key, v) {
        key = key.trim();
        if (key.startsWith("_")) return;
        if (key.startsWith("@")) {
          if (comments[v] != null) {
            _writeComments(comments[v], fields);
          }
          fields.write(key);
          fields.write(" ");
          fields.write(v);
          fields.writeln(";");
        } else {
          final bool optionalField = key.endsWith('?');
          final bool notNull = key.endsWith('!');
          if (optionalField || notNull) {
            key = key.substring(0, key.length - 1);
          }
          final bool shouldAppendOptionalFlag =
              !notNull && (optionalField || _nullable);

          if (comments[key] != null) {
            _writeComments(comments[key], fields);
          }
          if (!shouldAppendOptionalFlag) {
            fields.write('late ');
          }
          fields.write(getDataType(v, importSet, fileName, tag));
          if (shouldAppendOptionalFlag) {
            fields.write('?');
          }
          fields.write(" ");
          fields.write(key);
          //new line
          fields.writeln(";");
        }
        //indent
        fields.write("  ");
      });

      var dist = replaceTemplate(tpl, [
        fileName,
        className,
        className,
        fields.toString(),
        className,
        className,
        className
      ]);
      // Insert the imports at the head of dart file.
      var _import = importSet.join(";\r\n");
      _import += _import.isEmpty ? "" : ";";
      dist = dist.replaceFirst("%t", _import);
      //Create dart file
      File(dartFilePath)
        ..createSync(recursive: true)
        ..writeAsStringSync(dist);
      indexFile = exportIndexFile(dartFilePath, distDir, indexFile);
      print('done: ${f.path} -> $dartFilePath');
    }
  });
  if (indexFile.isNotEmpty) {
    final p = path.join(distDir, "index.dart");
    File(p).writeAsStringSync(indexFile);
    print('create index file: $p');
  }
  return indexFile.isNotEmpty;
}