generateDartTypes function

String generateDartTypes(
  1. List collections, {
  2. bool includeSystem = false,
})

Generates the Dart source for collections. System tables are skipped unless includeSystem is true.

Implementation

String generateDartTypes(
  List<dynamic> collections, {
  bool includeSystem = false,
}) {
  final list = _maps(collections)
      .where(
        (c) => c["name"] is String && (includeSystem || c["system"] != true),
      )
      .toList()
    ..sort((a, b) => (a["name"] as String).compareTo(b["name"] as String));

  final b = StringBuffer()
    ..writeln(
      "// Generated by `dart run rustabase:gen_types`. Do not edit by hand;",
    )
    ..writeln("// run the command again after changing your tables.")
    ..writeln("// ignore_for_file: type=lint")
    ..writeln();

  final names = <String, String>{};
  for (final c in list) {
    final table = c["name"] as String;
    final cls = pascalCase(table);
    names[table] = cls;
    final fields = _maps(c["fields"])
        .where(
          (f) =>
              f["name"] is String &&
              f["type"] != "password" &&
              f["hidden"] != true,
        )
        .toList();
    final cols = <_Col>[
      if (!fields.any((f) => f["name"] == "id"))
        _Col("id", "id", "String", _str),
      ...fields.map(_column),
    ];

    b
      ..writeln("/// Row of the `$table` table (${c["type"] ?? "base"}).")
      ..writeln("class $cls {")
      ..writeln("  const $cls({");
    for (final x in cols) {
      b.writeln("    required this.${x.prop},");
    }
    b
      ..writeln("    this.expand = const {},")
      ..writeln("  });")
      ..writeln()
      ..writeln("  /// Table name on the server.")
      ..writeln("  static const tableName = ${_lit(table)};")
      ..writeln();
    for (final x in cols) {
      b.writeln("  final ${x.type} ${x.prop};");
    }
    b
      ..writeln("  final Map<String, dynamic> expand;")
      ..writeln()
      ..writeln("  factory $cls.fromJson(Map<String, dynamic> json) => $cls(");
    for (final x in cols) {
      final v = "json[${_lit(x.name)}]";
      b.writeln(
        "        ${x.prop}: ${x.read.replaceAll(RegExp(r"\bv\b"), v)},",
      );
    }
    b
      ..writeln(
        "        expand: (json[\"expand\"] as Map?)?.cast<String, dynamic>() ?? const {},",
      )
      ..writeln("      );")
      ..writeln()
      ..writeln("  Map<String, dynamic> toJson() => {");
    for (final x in cols) {
      b.writeln("        ${_lit(x.name)}: ${x.prop},");
    }
    b
      ..writeln("      };")
      ..writeln("}")
      ..writeln();
  }

  b
    ..writeln("/// Every generated table: name -> JSON decoder.")
    ..writeln(
      "const Map<String, Object Function(Map<String, dynamic>)> rustabaseTables = {",
    );
  names.forEach((table, cls) => b.writeln("  ${_lit(table)}: $cls.fromJson,"));
  b.writeln("};");
  return b.toString();
}