113 lines
3.1 KiB
Dart
113 lines
3.1 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:ferry/ferry.dart';
|
|
import 'package:gql_http_link/gql_http_link.dart';
|
|
|
|
import '../../../shared/auth/telegram_session.dart' as telegram_auth;
|
|
|
|
class MapflowGraphqlClient {
|
|
factory MapflowGraphqlClient({
|
|
Client? client,
|
|
String? telegramInitData,
|
|
String? telegramLoginData,
|
|
String? mapflowSessionToken,
|
|
String endpoint = const String.fromEnvironment(
|
|
'API_BASE_URL',
|
|
defaultValue: '/graphql',
|
|
),
|
|
}) {
|
|
final resolvedTelegramInitData =
|
|
telegramInitData ?? telegram_auth.telegramInitData();
|
|
final resolvedTelegramLoginData =
|
|
telegramLoginData ?? telegram_auth.telegramLoginData();
|
|
final resolvedMapflowSessionToken =
|
|
mapflowSessionToken ?? telegram_auth.mapflowSessionToken();
|
|
|
|
return MapflowGraphqlClient._(
|
|
client:
|
|
client ??
|
|
Client(
|
|
link: HttpLink(
|
|
Uri.base.resolve(endpoint).toString(),
|
|
defaultHeaders: _headers(
|
|
resolvedTelegramInitData,
|
|
resolvedTelegramLoginData,
|
|
resolvedMapflowSessionToken,
|
|
),
|
|
),
|
|
),
|
|
telegramInitData: resolvedTelegramInitData,
|
|
telegramLoginData: resolvedTelegramLoginData,
|
|
mapflowSessionToken: resolvedMapflowSessionToken,
|
|
);
|
|
}
|
|
|
|
MapflowGraphqlClient._({
|
|
required Client client,
|
|
required this.telegramInitData,
|
|
required this.telegramLoginData,
|
|
required this.mapflowSessionToken,
|
|
}) : _client = client;
|
|
|
|
final Client _client;
|
|
final String telegramInitData;
|
|
final String telegramLoginData;
|
|
final String mapflowSessionToken;
|
|
|
|
bool get hasTelegramAuth =>
|
|
telegramInitData.isNotEmpty ||
|
|
telegramLoginData.isNotEmpty ||
|
|
mapflowSessionToken.isNotEmpty;
|
|
|
|
Future<TData> request<TData, TVars>(
|
|
OperationRequest<TData, TVars> request,
|
|
) async {
|
|
final response = await _client
|
|
.request(request)
|
|
.firstWhere((item) => !item.loading);
|
|
|
|
if (response.hasErrors) {
|
|
throw StateError(_errorMessage(response));
|
|
}
|
|
|
|
final data = response.data;
|
|
if (data == null) {
|
|
throw StateError('GraphQL response data is empty.');
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
void dispose() {
|
|
unawaited(_client.dispose());
|
|
}
|
|
|
|
static Map<String, String> _headers(
|
|
String telegramInitData,
|
|
String telegramLoginData,
|
|
String mapflowSessionToken,
|
|
) {
|
|
return {
|
|
if (telegramInitData.isNotEmpty) 'x-telegram-init-data': telegramInitData,
|
|
if (telegramLoginData.isNotEmpty)
|
|
'x-telegram-login-data': telegramLoginData,
|
|
if (mapflowSessionToken.isNotEmpty)
|
|
'x-mapflow-session-token': mapflowSessionToken,
|
|
};
|
|
}
|
|
|
|
String _errorMessage(OperationResponse<dynamic, dynamic> response) {
|
|
final graphQLErrors = response.graphqlErrors;
|
|
if (graphQLErrors != null && graphQLErrors.isNotEmpty) {
|
|
return graphQLErrors.map((error) => error.message).join('\n');
|
|
}
|
|
|
|
final linkException = response.linkException;
|
|
if (linkException != null) {
|
|
return linkException.toString();
|
|
}
|
|
|
|
return 'GraphQL request failed.';
|
|
}
|
|
}
|