manifest_dart_sdk 0.1.2+1
manifest_dart_sdk: ^0.1.2+1 copied to clipboard
A Dart SDK for Manifest - a lightweight micro-backend solution with minimal dependencies
Developed by 🦏 zoocityboy
Manifest Dart SDK #
A Dart client SDK for interacting with Manifest backend services. This SDK provides a clean and intuitive interface for communication with your Manifest backend, handling authentication, CRUD operations, and file uploads.
Features #
- 🔐 Authentication - Login, signup, and logout functionality
- 📝 Singles Management - Get and update single entities
- 📋 Collections Management - Full CRUD operations on collection entities
- 📎 File Uploads - Upload files and images
- 🖼️ Image Processing - Handle image uploads with multiple sizes
- 📄 Pagination Support - Paginate through large collections
Installation #
Add this package to your project's dependencies:
dependencies:
manifest_dart_sdk:
Then run:
dart pub get
Usage #
Initialize the client #
import 'package:manifest-dart-sdk/manifest-dart-sdk.dart';
void main() {
// Default URL is http://localhost:1111
final client = Manifest();
// Or specify a custom URL
final customClient = Manifest('https://your-manifest-backend.com');
}
Working with Singles #
Singles are standalone entities that don't belong to a collection.
// Get a single entity
var about = await client.single('about').get<Map<String, dynamic>>();
print('About page: ${about['title']}');
// Update a single entity (full replacement)
var updated = await client.single('about').update<Map<String, dynamic>>({
'title': 'Updated About Page',
'content': 'This is the updated about page content.'
});
// Partially update a single entity
var patched = await client.single('about').patch<Map<String, dynamic>>({
'title': 'Patched About Page'
});
Working with Collections #
Collections are groups of similar entities.
// Get a paginated list of items
var posts = await client.from('posts').find(page: 1, perPage: 10);
posts.data.forEach((post) {
print('- ${post['title']}');
});
// Get a single item by ID
var post = await client.from('posts').findOneById(1);
// Create a new item
var newPost = await client.from('posts').create({
'title': 'New Post',
'content': 'This is a new post'
});
// Update an item (full replacement)
var updatedPost = await client.from('posts').update(1, {
'title': 'Updated Post',
'content': 'This post was updated'
});
// Partially update an item
var patchedPost = await client.from('posts').patch(1, {
'title': 'Patched Post'
});
// Delete an item
int deletedId = await client.from('posts').delete(1);
Authentication #
// Login
bool loggedIn = await client.login('users', 'user@example.com', 'password123');
// Get current user
var currentUser = await client.from('users').me();
// Logout
client.logout();
// Signup
bool signedUp = await client.signup('users', 'newuser@example.com', 'password123');
File Uploads #
import 'dart:io';
import 'dart:typed_data';
// Upload a file
File file = File('document.pdf');
Uint8List fileBytes = await file.readAsBytes();
var uploadResult = await client.from('documents')
.upload('attachment', fileBytes, 'document.pdf');
print('Uploaded file path: ${uploadResult['path']}');
// Upload an image
File imageFile = File('image.jpg');
Uint8List imageBytes = await imageFile.readAsBytes();
var imageResult = await client.from('posts')
.uploadImage('featured_image', imageBytes, 'image.jpg');
print('Uploaded image paths: $imageResult');
// Get image URL by size
String imageUrl = client.imageUrl(imageResult, 'medium');
Error Handling #
The SDK provides a robust exception hierarchy for proper error handling:
try {
await client.from('posts').findOneById(999);
} on NotFoundException catch (e) {
print('Post not found: ${e.message}');
} on AuthenticationException catch (e) {
print('Authentication error: ${e.message}');
} on ValidationException catch (e) {
print('Validation error:');
if (e.validationErrors != null) {
e.validationErrors!.forEach((field, errors) {
print(' - $field: ${errors.join(', ')}');
});
}
} on ApiException catch (e) {
print('API error (${e.statusCode}): ${e.message}');
} on NetworkException catch (e) {
print('Network error: ${e.message}');
print('Original exception: ${e.originalException}');
} on ManifestException catch (e) {
print('General SDK error: ${e.message}');
} catch (e) {
print('Unexpected error: $e');
}
Exception Types #
The SDK throws the following exception types:
Exception Type | Description | Status Codes |
---|---|---|
NetworkException |
Network connectivity issues | N/A |
AuthenticationException |
Authentication issues | 401, 403 |
ValidationException |
Validation errors | 422 |
NotFoundException |
Resource not found | 404 |
ServerException |
Server-side errors | 500-599 |
RateLimitException |
Rate limit exceeded | 429 |
ApiException |
Generic API errors | Any error status code |
ManifestException |
Base exception class | N/A |
Accessing Error Details #
Most exception types provide additional error details:
try {
// Operation that might fail
} on ApiException catch (e) {
print('Status code: ${e.statusCode}');
print('Error message: ${e.message}');
print('Response body: ${e.body}');
print('Error data: ${e.errorData}');
}
Validation errors provide field-specific error messages:
try {
await client.from('posts').create({'incomplete': 'data'});
} on ValidationException catch (e) {
e.validationErrors?.forEach((field, errors) {
print('$field: ${errors.join(', ')}');
});
}
Type Safety #
You can use generics to get better type safety:
// Define a class for your entities
class Post {
final int id;
final String title;
final String content;
Post({required this.id, required this.title, required this.content});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
id: json['id'],
title: json['title'],
content: json['content'],
);
}
}
// Use the fromJson parameter with find to get typed objects
var posts = await client.from('posts').find<Post>(
fromJson: (json) => Post.fromJson(json)
);
// Now posts.data contains a List<Post>
for (var post in posts.data) {
print('Post ${post.id}: ${post.title}');
}
WASM Compatibility #
This package is compatible with Dart's WebAssembly (WASM) target. All HTTP operations use the http
package, which supports WASM and web environments. No dart:io
dependencies are present.
Complete Example #
See the /example
folder for a complete example of using the SDK.