flutter_app_core_freezed

Core building blocks for Flutter apps: typed HTTP client, Result<T> wrapper, BLoC base classes and SharedPreferences token storage.


License
MIT

Documentation

flutter_app_core

A lightweight Flutter package that provides the core building blocks for production-ready apps: typed HTTP client, functional Result<T> wrapper, BLoC-based state management base classes, and secure token storage.


Features

  • 🌐 ApiClient — HTTP client with automatic Bearer-token injection, get, post, put and delete methods, and robust error handling.
  • Result<T> — functional success/failure wrapper with a when() pattern to avoid null-checks.
  • ⚠️ AppError — typed exception that carries an HTTP status code alongside the human-readable message.
  • 🔄 BaseCubit / BaseState — BLoC-based state machine that normalises every async operation into Loading, Success<T>, or Error states.
  • 🔑 AuthStorage — save, retrieve and clear the auth token from SharedPreferences with a single line.

Getting started

Add the package to your pubspec.yaml:

dependencies:
  flutter_app_core: ^0.0.1

Then run:

flutter pub get

Usage

ApiClient

import 'package:flutter_app_core/flutter_app_core.dart';

final client = ApiClient(baseUrl: 'https://api.example.com');

// Attach a token after login
client.setToken('my_jwt_token');

// GET
final result = await client.get('/users');
result.when(
  success: (data) => print(data),
  failure: (error) => print(error),
);

// POST
final postResult = await client.post('/users', body: {'name': 'Juan'});

// PUT
final putResult = await client.put('/users/1', body: {'name': 'Juan Updated'});

// DELETE
final deleteResult = await client.delete('/users/1');

Result<T>

Result<String> fetchName() => Result.success('Flutter');

final result = fetchName();

final greeting = result.when(
  success: (name) => 'Hello, $name!',
  failure: (e) => 'Error: $e',
);

BaseCubit / BaseState

class UserCubit extends BaseCubit<User> {
  final ApiClient _client;

  UserCubit(this._client);

  Future<void> loadUser(int id) async {
    setLoading();
    final result = await _client.get('/users/$id');
    result.when(
      success: (data) => setData(User.fromJson(data)),
      failure: (e) => setError(e.toString()),
    );
  }
}

In your widget:

BlocBuilder<UserCubit, BaseState<User>>(
  builder: (context, state) {
    if (state is Loading) return CircularProgressIndicator();
    if (state is Success<User>) return Text(state.data.name);
    if (state is Error) return Text(state.message);
    return SizedBox.shrink();
  },
)

AuthStorage

final storage = AuthStorage();

// Save token after login
await storage.saveToken('my_jwt_token');

// Retrieve token
final token = await storage.getToken();

// Clear on logout
await storage.clear();

Additional information

  • File issues or feature requests on the GitHub repository.
  • Contributions are welcome — please open a PR with a clear description of the change.
  • Minimum SDK: Dart ^3.6.0 / Flutter >=1.17.0.