artemis_timatic
A lightweight, strongly-typed Dart/Flutter client for your Timatic-powered API.
Handles auth tokens for you and exposes simple methods to fetch locations, parameters, accepted values, and to submit the main Timatic document request.
- ✅ Null-safe
- ✅ Built on
dio - ✅ Token auto-injected after login
- ✅ Json-serializable models
- ✅ Friendly typed errors
Installation
Add to your app’s pubspec.yaml:
dependencies:
artemis_timatic: ^0.1.0
If you’re testing locally:
dependencies:
artemis_timatic:
path: ../artemis_timatic
Or from git:
dependencies:
artemis_timatic:
git:
url: https://github.com/your-org/artemis_timatic.git
ref: main
Consumers do not need to run code generation. That’s done in this package.
Quick Start
import 'package:artemis_timatic/timatic.dart';
import 'package:artemis_timatic/src/models/auth_request.dart'; // or export in root if you prefer
void main() async {
// 1) Create client + API
final client = TimaticClient(
TimaticClientOptions(baseUrl: 'https://your-api.example.com'),
);
final api = TimaticApi(client);
// 2) Login — pass app/device/network as raw JSON maps
await api.login(LoginRequest(
username: 'superadmin',
password: '••••••••',
app: {"name": "DCS One", "id": "1e5rt71e"},
device: {"type": 2, "model": "MacBookPro"}, // anything your API expects
network: {"type": 0, "ip": "192.168.1.5"},
));
// Token is now stored and auto-attached to all future requests.
// 3) Call endpoints
final airports = await api.listLocationsByType(LocationType.AIRPORT, name: 'Istanbul');
final params = await api.getParameters(codes: ['pets']);
final accepted = await api.getAcceptedValues(
countryCode: 'TR',
parameter: 'docIssueCountry',
ruleSetTypes: ['REQDOC'],
);
final resp = await api.submitDocumentRequest(
DocumentRequest(
documentDetails: [
DocumentDetail(
documentCode: 'OFFICIALPASSPORT',
documentExpiryDate: '2024-01-31',
documentIssueCountry: 'AFG',
),
],
itineraryDetails: ItineraryDetails(
segments: [
ItinerarySegment(
arrival: ItinPoint(
date: '2023-12-28',
time: '08:54',
dateTime: '2023-12-28T08:54:05',
point: 'AAH',
type: LocationType.AIRPORT,
),
departure: ItinPoint(
date: '2023-12-28',
time: '08:54',
dateTime: '2023-12-28T08:54:05',
point: 'IST',
type: LocationType.AIRPORT,
),
processingEntity: 'ABOMIS DOC CHECK',
),
],
),
passengerDetails: PassengerDetails(
birthDate: '2023-12-13',
nationality: 'ALB',
),
),
);
print('Transaction: ${resp.transactionId} Result: ${resp.evaluationResult}');
}
What’s Included
Auth & Token Handling
api.login(LoginRequest)posts your credentials and rawapp/device/networkmaps.- The returned
tokenis stored insideTimaticClient. - All subsequent requests automatically add:
Authorization: Bearer <token> - You can read/override if needed:
client.setAuthToken('new-token'); print(client.authToken);
Endpoints
// Locations
Future<List<Location>> listLocationsByType(
LocationType type, { String? code, String? name });
Future<List<Location>> searchLocations({
List<LocationType>? types, String? code, String? name });
// Parameters
Future<ParametersEnvelope> getParameters({
required List<String> codes, String? name });
// Accepted Values
Future<AcceptedValuesEnvelope> getAcceptedValues({
required String countryCode,
required String parameter,
List<String>? ruleSetTypes });
// Main Timatic Request
Future<DocumentResponse> submitDocumentRequest(DocumentRequest body);
Key Models (selection)
LoginRequest(uses rawMap<String,dynamic>forapp,device,network)Location,LocationTypeParametersEnvelope,ParameterItem,ParameterValueAcceptedValuesEnvelope,AcceptedRuleSet,AcceptedParameter,AcceptedValueDocumentRequest,DocumentDetail,ItineraryDetails,ItinerarySegment,ItinPoint,PassengerDetailsDocumentResponse,EvalResult,SegmentResult,RuleSetEvaluation,Regulation,RichTextBlock
Errors
All methods throw typed errors so you can handle them precisely:
TimaticError– base errorTimaticNetworkError– networking/HTTP issues (hasstatusCode)TimaticParsingError– unexpected JSON shapes
Example:
try {
final resp = await api.submitDocumentRequest(req);
} on TimaticNetworkError catch (e) {
// e.statusCode, e.message
} on TimaticParsingError catch (e) {
// backend changed response shape?
} on TimaticError catch (e) {
// general fallback
}
Configuration
final client = TimaticClient(TimaticClientOptions(
baseUrl: 'https://your-api',
apiKey: null, // if your gateway needs it (sent as X-API-Key)
headers: {'X-Custom': '1'},
connectTimeout: Duration(seconds: 10),
sendTimeout: Duration(seconds: 20),
receiveTimeout: Duration(seconds: 20),
));
If your auth header isn’t standard Bearer, change the interceptor in
TimaticClient.
HTML Texts
Some regulations include HTML in RichTextBlock.text.
Render it in your app with your favorite HTML widget, or strip tags if you need plain text.
Contributing (for maintainers)
This package uses json_serializable.
Install dev deps and generate code:
dart pub get
dart run build_runner build --delete-conflicting-outputs
Internal dependencies (already in this package’s pubspec.yaml):
dependencies:
dio: ^5.7.0
json_annotation: ^4.9.0
dev_dependencies:
build_runner: ^2.4.11
json_serializable: ^6.9.0
flutter_lints: ^4.0.0
Roadmap
Optional token persistence (e.g.,SharedPreferences) so login survives app restartsAuto-relogin/refresh on 401More typed enums for rule set types / applicability flagsHelpers to sanitize or summarize HTML advisories
License
MIT (or your preferred license). Add a LICENSE file at the repo root.
Support
Issues & PRs welcome. For private API questions, share example payloads and we’ll update models/endpoints quickly.
Happy shipping ✈️