Skip to content

nrbnlulu/shalom

Repository files navigation

shalom

note that shalom is currently in beta, while the public API's are not expected to change much, the internal behaviour might.

Installation

  1. Build the CLI from source:
cargo install --git https://github.com/nrbnlulu/shalom.git --branch main shalom_dart_codegen
  1. add flutter deps
dart pub add shalom_core:'{"git":{"url": "https://github.com/nrbnlulu/shalom.git", "path": "dart/shalom_core"}}'
dart pub add shalom_flutter:'{"git":{"url": "https://github.com/nrbnlulu/shalom.git", "path": "dart/shalom_flutter"}}'

CLI Usage

The shalom CLI provides commands to generate Dart code from your GraphQL schema and operations.

Commands

Generate

Generate Dart code from GraphQL schema and operations:

shalom generate [OPTIONS]

Options:

  • -p, --path <PATH>: Path to the project directory (defaults to current directory)
  • -s, --strict: Fail on first error instead of continuing

Example:

shalom generate --path ./my-project --strict

Watch

Watch for changes in GraphQL files (.graphql and .gql) and automatically regenerate code:

shalom watch [OPTIONS]

Examples

How to: Custom scalars

  1. make sure to add shalom.yml in project root. its content should look like this
custom_scalars:
  Point:
    graphql_name: "Point"
    output_type: 
      import_path: "package:dart_tests/point.dart"
      symbol_name: "Point"
      
    impl_symbol:
      import_path: "package:dart_tests/point.dart"
      symbol_name: "pointScalarImpl"

and these are the scalar implementation (modify to fit your needs)

import 'package:shalom_core/shalom_core.dart';

class Point {
  final int x;
  final int y;

  const Point({required this.x, required this.y});

  @override
  String toString() => 'Point(x: $x, y: $y)';

  @override
  bool operator ==(Object other) {
    return identical(this, other) ||
        (other is Point && other.x == x && other.y == y);
  }

  @override
  int get hashCode => Object.hash(x, y);
}

class _PointScalarImpl implements CustomScalarImpl<Point> {
  @override
  Point deserialize(dynamic raw) {
    if (raw is Map<String, dynamic>) {
      // Check if keys exist and are integers before using them.
      if (raw['x'] is! int || raw['y'] is! int) {
        throw FormatException(
          "Point fields 'x' and 'y' must be present and must be integers.",
        );
      }
      return Point(x: raw['x'], y: raw['y']);
    }

    if (raw is! String) {
      throw FormatException(
        "Expected String or Map for Point, got ${raw.runtimeType}",
      );
    }

    // Handles string-like: "POINT (12, 34)"
    final regex = RegExp(r'POINT\s*\((-?\d+),\s*(-?\d+)\)');
    final match = regex.firstMatch(raw);
    if (match == null) throw FormatException("Invalid POINT format: $raw");

    return Point(x: int.parse(match[1]!), y: int.parse(match[2]!));
  }

  @override
  dynamic serialize(Point value) {
    return "POINT (${value.x}, ${value.y})";
  }
}

// This is referenced in shalom.yml
final pointScalarImpl = _PointScalarImpl();

Roadmap

  • builtin scalars
  • custom scalars
  • enums
  • object selection
  • nested objects
  • union
  • interface
  • fragments
  • list of
    • scalars
    • custom scalars
    • objects
    • enums
    • unions
    • interface
    • fragments
    • nested list
  • Node interface real time updates.
  • defer / stream
  • input
    • scalar
    • custom scalar
    • object
    • enum
    • oneOf
    • list of
      • scalar
      • custom scalar
      • object
      • enum
      • oneOf

About

GraphQL client for dart and flutter.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors