typed_deep_links 0.1.0 copy "typed_deep_links: ^0.1.0" to clipboard
typed_deep_links: ^0.1.0 copied to clipboard

Type-safe, router-agnostic deep links with generated URI parsing and building.

typed_deep_links #

Type-safe deep links without coupling domain code to a router.

Declare URI shape beside immutable data classes. build_runner generates parsing, validation, exhaustive-pattern-friendly values, and reverse URL building. Use generated values with GoRouter, AutoRoute, Navigator, server handlers, or any custom router.

import 'package:typed_deep_links/typed_deep_links.dart';

part 'links.g.dart';

@DeepLink('/orders/')
final class OrderLink {
  const OrderLink({required this.id, this.source});

  final int id;

  @QueryParameter()
  final String? source;
}

Generate code:

dart run build_runner build --delete-conflicting-outputs

Parse and pattern match:

final link = DeepLinks.parse(Uri.parse('/orders/42?source=email'));

switch (link) {
  case OrderLink(:final id, :final source):
    openOrder(id, source: source);
}

Build URLs:

const OrderLink(id: 42, source: 'push').toUri();
// /orders/42?source=push

DeepLinks.toUri(const OrderLink(id: 42));
// /orders/42

Route syntax #

Use explicit placeholders when useful:

@DeepLink('/shops/:shopId/orders/:orderId')
final class ShopOrderLink {
  const ShopOrderLink({required this.shopId, required this.orderId});

  final int shopId;
  final int orderId;
}

A path ending in / appends remaining unannotated constructor fields as path segments. This is why @DeepLink('/orders/') maps id to /orders/42.

Parameter annotations control other placements:

@DeepLink('/search')
final class SearchLink {
  const SearchLink({this.query, this.section});

  @QueryParameter('q')
  final String? query;

  @FragmentParameter()
  final String? section;
}
  • @PathParameter('name'): maps a field to a placeholder or appended segment.
  • @QueryParameter('key'): maps a field to one query value.
  • @FragmentParameter(): maps one field to the URI fragment.
  • scheme and host: constrain absolute app/universal links.
  • caseSensitive: false: allows case-insensitive static path segments.

Supported field types: String, int, double, num, bool, DateTime, Uri, and enums. Nullable query/fragment fields are optional. Path fields must be non-nullable. Boolean parsing accepts true, false, 1, and 0.

Failure handling #

DeepLinks.parse throws:

  • DeepLinkNotFoundException when no route matches.
  • DeepLinkFormatException when a route matches but a required or typed value is invalid.

Alternatives:

final value = DeepLinks.tryParse(uri); // null only when no route matches

switch (DeepLinks.parseResult(uri)) {
  case DeepLinkSuccess(:final value):
    handle(value);
  case DeepLinkFailure(:final error):
    log(error);
}

Router integration #

No router dependency is required. Keep a small adapter at app boundary:

// GoRouter redirect/route builder, AutoRoute guard, or Navigator handler:
Object? parseLocation(String location) =>
    DeepLinks.tryParse(Uri.parse(location));

String restoreLocation(Object link) => DeepLinks.toUri(link).toString();

Absolute links work with the same API:

@DeepLink('/orders/:id', scheme: 'myapp', host: 'open')
final class AppOrderLink { /* ... */ }

For web origins or API bases, resolve relative routes while building:

link.toUri(baseUri: Uri.parse('https://example.com/app/'));

Organization and generated registry #

One DeepLinks registry is generated per Dart library. Put related annotated classes in one library, using part files if desired. This avoids global state, runtime reflection, and router-specific registration.

Generated route order prefers more static segments before dynamic routes, so /orders/new wins over /orders/:id. Conflicting route shapes fail generation.

Package setup #

Add runtime and generator dependency:

dart pub add typed_deep_links
dart pub add --dev build_runner

Flutter projects use the same commands with dart run build_runner.

See example/example.dart for a complete example.

License #

MIT.

0
likes
0
points
188
downloads

Publisher

verified publisherpinz.dev

Weekly Downloads

Type-safe, router-agnostic deep links with generated URI parsing and building.

Repository (GitHub)
View/report issues

Topics

#deep-linking #code-generation #routing #uri #flutter

License

unknown (license)

Dependencies

analyzer, build, meta, source_gen

More

Packages that depend on typed_deep_links