api_gen

A comprehensive Dart code generator for creating model classes with fromJson and toJson methods from JSON schemas. Features a robust CLI with multiple commands, comprehensive exception handling, and support for both legacy and standard JSON Schema formats.


Installation

Add api_gen to your pubspec.yaml:

dependencies:
  api_gen: ^0.1.0

Or activate globally to use as a CLI:

dart pub global activate api_gen

CLI Usage

Generate Models

# Basic usage
api_gen generate --schema api.json --dir lib/models

# Short form
api_gen generate -s api.json -d lib/models

# Force legacy format
api_gen generate -s api.json -d lib/models --legacy

Validate Schema

# Validate schema structure
api_gen validate --schema api.json

# Short form
api_gen validate -s api.json

Watch for Changes

# Watch schema file and regenerate on changes
api_gen watch --schema api.json --dir lib/models

# Custom polling interval (default: 2 seconds)
api_gen watch -s api.json -d lib/models --interval 5

Get Help

# General help
api_gen --help

# Command-specific help
api_gen generate --help
api_gen validate --help
api_gen watch --help

Programmatic Usage

Using the High-Level ApiGenClient

import 'package:api_gen/api_gen.dart';

void main() async {
  final client = ApiGenClient();

  // Generate from file
  final result = await client.generateFromFile('api.json', 'lib/models');

  if (result.isSuccessful) {
    print('Models generated successfully');
  } else {
    final failure = result as Failure<void>;
    print('Error: ${failure.exception}');
  }
}

Available Methods

// 1. Generate from file
await client.generateFromFile('schema.json', 'lib/models');

// 2. Generate from schema Map
final schema = {'User': {'id': 'String', 'name': 'String'}};
await client.generateFromSchema(schema, 'lib/models');

// 3. Generate from JSON string
const jsonString = '{"Product": {"id": "String"}}';
await client.generateFromJsonString(jsonString, 'lib/models');

Schema Formats

Legacy Format (Simple)

{
  "user": {
    "id": "int",
    "name": "String",
    "email": { "type": "String", "required": false },
    "profile": { "type": "Profile", "required": true }
  },
  "profile": {
    "age": "int",
    "bio": { "type": "String", "required": false }
  }
}

Standard JSON Schema Format

{
  "$defs": {
    "User": {
      "type": "object",
      "properties": {
        "id": { "type": "string" },
        "name": { "type": "string" },
        "email": { "type": "string" }
      },
      "required": ["id", "name"]
    }
  }
}

Exception Handling

The package provides comprehensive exception handling with specific exception types:

final result = await client.generateFromFile('schema.json', 'models');

if (result.isFailure) {
  final failure = result as Failure<void>;
  final exception = failure.exception;

  if (exception is FileOperationException) {
    print('File error: ${exception.message}');
  } else if (exception is SchemaValidationException) {
    print('Schema error: ${exception.message}');
  } else if (exception is CodeGenerationException) {
    print('Generation error: ${exception.message}');
  } else if (exception is JsonParsingException) {
    print('JSON error: ${exception.message}');
  }
}

Exception Types:

  • FileOperationException: File I/O errors (file not found, permission denied, etc.)
  • SchemaValidationException: Invalid or empty schemas
  • CodeGenerationException: Model generation errors
  • JsonParsingException: JSON parsing errors

Examples

See the example/ directory for comprehensive examples:

  • main.dart - Basic usage with ApiGenClient
  • comprehensive_example.dart - All usage patterns and error handling
  • usage_guide.dart - Step-by-step guide
  • API_USAGE.md - Detailed API documentation

Quick Example

import 'package:api_gen/api_gen.dart';

void main() async {
  final client = ApiGenClient();

  // Generate models with proper error handling
  final result = await client.generateFromFile('api.json', 'lib/models');

  if (result.isSuccessful) {
    print('Models generated successfully');
  } else {
    final failure = result as Failure<void>;
    print('Error: ${failure.exception}');
  }
}

Advanced Usage

Direct Generator Usage

For more control, you can use the generators directly:

import 'package:api_gen/api_gen.dart';

// For legacy format
final legacyGenerator = DartModelGenerator('lib/models');
legacyGenerator.generate(schema);

// For standard JSON Schema format
final generator = ModelGenerator('lib/models');
final result = generator.generate(schema);

Custom Error Handling

Future<void> generateWithRetry(String schemaPath, String outputDir) async {
  final client = ApiGenClient();

  for (int attempt = 1; attempt <= 3; attempt++) {
    final result = await client.generateFromFile(schemaPath, outputDir);

    if (result.isSuccessful) return;

    if (attempt < 3) {
      print('Attempt $attempt failed, retrying...');
      await Future.delayed(Duration(seconds: attempt));
    } else {
      final failure = result as Failure<void>;
      throw Exception('Failed after 3 attempts: ${failure.exception}');
    }
  }
}

Testing

The package includes comprehensive test coverage:

# Run all tests
dart test

# Run specific test suites
dart test test/core_test.dart
dart test test/api_gen_test.dart
dart test test/cli/
dart test test/schema/
dart test test/generator/
dart test test/integration/

Test Coverage:

  • ✅ CLI command functionality
  • ✅ Schema validation and parsing
  • ✅ Model generation (both formats)
  • ✅ Error handling and exceptions
  • ✅ File operations and I/O
  • ✅ Integration tests

Changelog

You can read the changes for api_gen from this Changelog.


Contributing

Contributions are welcome! Please open issues or submit pull requests.


License

This project is licensed under the MIT License.

Libraries

api_gen
extensions
Optional global extensions for user access