Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ajinasokan/dartgen

An inline generator collection for Dart & Flutter projects
https://github.com/ajinasokan/dartgen

code-generation dart flutter

Last synced: 7 days ago
JSON representation

An inline generator collection for Dart & Flutter projects

Awesome Lists containing this project

README

        

# DartGenerate

An inline generator collection for Dart. Generate JSON serializers, enums with mapped values and iterables, export index etc. for your Flutter or Dart projects.

Unlike the standard code generators DartGenerate doesn't produce `.g.dart` files. Instead the code is inserted into the actual definition itself. This is very similar to how `dartfmt` works. This can also be compared to how Java IDEs generate the getters and setters for fields. The objective of this flow is to keep the project clean and make codebase more readable.

## Features

- Generate enums with serializers.
- Generate model serializers. You can add enums inside these models as well.
- Generate index from a directory. This file will export all the `.dart` files.
- Embed files from a directory.
- Watches for file changes.
- Config file to setup multiple generators.
- Option to enable recursive travel of dirs.

## Install

From pub:

```shell
$ pub global activate dartgenerate
```

From git:

```shell
$ pub global activate --source git https://github.com/ajinasokan/dartgen
```

Make sure you [set the $PATH](https://dart.dev/tools/pub/cmd/pub-global#running-a-script-from-your-path) for pub. To verify run:

```shell
$ dartgenerate

No dartgenerate.json found in this directory.

Example config:
{
"dir": "lib",
"generators": [
{ "dir": "lib/models", "type": "model" },
{ "dir": "lib/models", "type": "index" },
{ "dir": "lib/constants", "type": "constant" },
{ "dir": "lib/constants", "type": "index" },
],
}
```

To run in watch mode:

```shell
$ dartgenerate watch
```

## Config

```json
{
"dir": "lib",
"generators": [
{ "dir": "lib/models", "type": "model" },
{ "dir": "lib/models", "type": "index" },
{ "dir": "lib/constants", "type": "constant" },
{ "dir": "lib/constants", "type": "index" },
{ "dir": "lib/components", "type": "index", "recursive": true },
{ "dir": "lib/screens", "type": "index", "recursive": true },
{ "dir": "lib/svgs", "type": "embed" }
]
}
```

Explanation:

`.dir` directory to watch file changes. Run `dartgenerate watch` to take this into consideration.

`.generators` list of all generators to run. This can be `model`, `constant`, `index` or `embed` generators. You can have more than one kind of generator executing in same directory.

`.generators.dir` sets the directory to run a particular generator.

`.generators.type` sets the type of the generator to run in the above directory.

`.generators.recursive` sets whether to run this generator recursively in the directory.

An example of usage can be found [here](EXAMPLE.md) and in `/test` directory.

## Code Generation

The generation process takes the code and the annotations inside it as the input and generates the appropriate code and injects back to the code. Clearly this is mutation of the code, just like how `dartfmt` is. Hence it is adviced to have your code version controlled, with git or by any other means, so that you can reverse if the generation caused any damage.

### Generating models

Code you write should look like this:

```dart
import 'dart:convert';

@pragma('model')
class Address {

@pragma('json:street_name')
String streetName = "NA";

}
```

`@pragma('model')` tells DartGenerate to generate model for this class. This includes constructor, map conversion, json conversion and serialization methods. `@pragma('json:street_name')` on a field gives the alias for that field in the json. If you don't specify an alias like this it will not be part of the serialization. You can specify a default value for the field. This will be used if you didn't initialize the field, the field doesn't exist or if the field is null in the json.

You can use all the data types that are supported in json, lists and maps of them, other models and enums with serializers generated by DartGenerate and Decimal.

Optionally you can add `@pragma('model', 'patchWith,clone')` flags to generate field patching and cloning methods. This clone method only does shallow clones. If you have to do deep clones you can use `toJson` and `fromJson` methods.

You can keep additional methods in the models and they will be kept intact.

### Generating enums

Define your enums like this:

```dart
@pragma('enum')
class Color {
static const Red = Color('red');
static const Green = Color('green');
}
```

DartGenerate wil generate the iterators, equivalence checks etc. These enums will be identified during the model generation. So they will be serialized properly.

### Generating index of exports

If you have a really large project its easier if all the dart files are exported. Dart is very good at handling cyclic imports given there are no name collisions.

If you enable index generation in a directory by defining in the `dartgenerate.json` it will generate `index.dart` in that directory with:

```dart
export 'address.dart';
export 'person.dart';
```

If you are in watch mode this will be automatically updated on addition/deletion of files.

### Embedding files

This is useful if you want to embedd small textual files like SVG, HTML, CSV etc. Embedding in the code instead of assets will help you access this synchronously and instantaneously. Bear in mind, if the file size is really big it will also increase the app's binary size which can result in slower load times.

You can enable embedding generator in `dartgenerate.json` for a directory and it will generate `index.dart` with:

```dart
final eulatxt = 'MIT License';
final imagesvg =
'\n\n\n\n\n \n Sorry, your browser does not support inline SVG. \n \n \n\n\n';
```

## License

DartGenerate is licensed under the MIT license