checkpoint
This commit is contained in:
+121
-6
@@ -6,13 +6,16 @@ import 'types.dart';
|
||||
import 'openapi_config.dart';
|
||||
import '../utils/logging_interceptor.dart';
|
||||
import '../utils/http_client_factory.dart';
|
||||
import '../services/auth_service.dart';
|
||||
|
||||
class CqrsApiClient {
|
||||
final ApiClientConfig config;
|
||||
final AuthService? authService;
|
||||
late final http.Client _httpClient;
|
||||
|
||||
CqrsApiClient({
|
||||
required this.config,
|
||||
this.authService,
|
||||
http.Client? httpClient,
|
||||
}) {
|
||||
_httpClient = httpClient ?? InterceptedClient.build(
|
||||
@@ -29,10 +32,11 @@ class CqrsApiClient {
|
||||
required String endpoint,
|
||||
required Serializable query,
|
||||
required T Function(Map<String, dynamic>) fromJson,
|
||||
bool isRetry = false,
|
||||
}) async {
|
||||
try {
|
||||
final url = Uri.parse('$baseUrl/api/query/$endpoint');
|
||||
final headers = _buildHeaders();
|
||||
final headers = await _buildHeaders();
|
||||
|
||||
final response = await _httpClient
|
||||
.post(
|
||||
@@ -42,6 +46,20 @@ class CqrsApiClient {
|
||||
)
|
||||
.timeout(config.timeout);
|
||||
|
||||
if (response.statusCode == 401 && !isRetry && authService != null) {
|
||||
final refreshResult = await authService!.refreshAccessToken();
|
||||
return refreshResult.when(
|
||||
success: (token) => executeQuery(
|
||||
endpoint: endpoint,
|
||||
query: query,
|
||||
fromJson: fromJson,
|
||||
isRetry: true,
|
||||
),
|
||||
onError: (error) => _handleResponse<T>(response, fromJson),
|
||||
cancelled: () => _handleResponse<T>(response, fromJson),
|
||||
);
|
||||
}
|
||||
|
||||
return _handleResponse<T>(response, fromJson);
|
||||
} on TimeoutException {
|
||||
return Result.error(ApiError.timeout());
|
||||
@@ -62,12 +80,13 @@ class CqrsApiClient {
|
||||
required int page,
|
||||
required int pageSize,
|
||||
List<FilterCriteria>? filters,
|
||||
bool isRetry = false,
|
||||
}) async {
|
||||
try {
|
||||
final url = Uri.parse(
|
||||
'$baseUrl/api/query/$endpoint?page=$page&pageSize=$pageSize',
|
||||
);
|
||||
final headers = _buildHeaders();
|
||||
final headers = await _buildHeaders();
|
||||
|
||||
final queryData = {
|
||||
...query.toJson(),
|
||||
@@ -83,6 +102,23 @@ class CqrsApiClient {
|
||||
)
|
||||
.timeout(config.timeout);
|
||||
|
||||
if (response.statusCode == 401 && !isRetry && authService != null) {
|
||||
final refreshResult = await authService!.refreshAccessToken();
|
||||
return refreshResult.when(
|
||||
success: (token) => executePaginatedQuery(
|
||||
endpoint: endpoint,
|
||||
query: query,
|
||||
itemFromJson: itemFromJson,
|
||||
page: page,
|
||||
pageSize: pageSize,
|
||||
filters: filters,
|
||||
isRetry: true,
|
||||
),
|
||||
onError: (error) => _handlePaginatedResponse<T>(response, itemFromJson, page, pageSize),
|
||||
cancelled: () => _handlePaginatedResponse<T>(response, itemFromJson, page, pageSize),
|
||||
);
|
||||
}
|
||||
|
||||
return _handlePaginatedResponse<T>(response, itemFromJson, page, pageSize);
|
||||
} on TimeoutException {
|
||||
return Result.error(ApiError.timeout());
|
||||
@@ -99,10 +135,11 @@ class CqrsApiClient {
|
||||
Future<Result<void>> executeCommand({
|
||||
required String endpoint,
|
||||
required Serializable command,
|
||||
bool isRetry = false,
|
||||
}) async {
|
||||
try {
|
||||
final url = Uri.parse('$baseUrl/api/command/$endpoint');
|
||||
final headers = _buildHeaders();
|
||||
final headers = await _buildHeaders();
|
||||
|
||||
final response = await _httpClient
|
||||
.post(
|
||||
@@ -112,6 +149,31 @@ class CqrsApiClient {
|
||||
)
|
||||
.timeout(config.timeout);
|
||||
|
||||
if (response.statusCode == 401 && !isRetry && authService != null) {
|
||||
final refreshResult = await authService!.refreshAccessToken();
|
||||
return refreshResult.when(
|
||||
success: (token) => executeCommand(
|
||||
endpoint: endpoint,
|
||||
command: command,
|
||||
isRetry: true,
|
||||
),
|
||||
onError: (error) {
|
||||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||
return Result.success(null);
|
||||
} else {
|
||||
return _handleErrorResponse(response);
|
||||
}
|
||||
},
|
||||
cancelled: () {
|
||||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||
return Result.success(null);
|
||||
} else {
|
||||
return _handleErrorResponse(response);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||
return Result.success(null);
|
||||
} else {
|
||||
@@ -133,10 +195,11 @@ class CqrsApiClient {
|
||||
required String endpoint,
|
||||
required Serializable command,
|
||||
required T Function(Map<String, dynamic>) fromJson,
|
||||
bool isRetry = false,
|
||||
}) async {
|
||||
try {
|
||||
final url = Uri.parse('$baseUrl/api/command/$endpoint');
|
||||
final headers = _buildHeaders();
|
||||
final headers = await _buildHeaders();
|
||||
|
||||
final response = await _httpClient
|
||||
.post(
|
||||
@@ -146,6 +209,20 @@ class CqrsApiClient {
|
||||
)
|
||||
.timeout(config.timeout);
|
||||
|
||||
if (response.statusCode == 401 && !isRetry && authService != null) {
|
||||
final refreshResult = await authService!.refreshAccessToken();
|
||||
return refreshResult.when(
|
||||
success: (token) => executeCommandWithResult(
|
||||
endpoint: endpoint,
|
||||
command: command,
|
||||
fromJson: fromJson,
|
||||
isRetry: true,
|
||||
),
|
||||
onError: (error) => _handleResponse<T>(response, fromJson),
|
||||
cancelled: () => _handleResponse<T>(response, fromJson),
|
||||
);
|
||||
}
|
||||
|
||||
return _handleResponse<T>(response, fromJson);
|
||||
} on TimeoutException {
|
||||
return Result.error(ApiError.timeout());
|
||||
@@ -164,11 +241,13 @@ class CqrsApiClient {
|
||||
required String filePath,
|
||||
required String fieldName,
|
||||
Map<String, String>? additionalFields,
|
||||
bool isRetry = false,
|
||||
}) async {
|
||||
try {
|
||||
final url = Uri.parse('$baseUrl/api/command/$endpoint');
|
||||
final headers = await _buildHeaders();
|
||||
final request = http.MultipartRequest('POST', url)
|
||||
..headers.addAll(_buildHeaders())
|
||||
..headers.addAll(headers)
|
||||
..files.add(await http.MultipartFile.fromPath(fieldName, filePath));
|
||||
|
||||
if (additionalFields != null) {
|
||||
@@ -178,6 +257,33 @@ class CqrsApiClient {
|
||||
final response = await request.send().timeout(config.timeout);
|
||||
final responseBody = await response.stream.bytesToString();
|
||||
|
||||
if (response.statusCode == 401 && !isRetry && authService != null) {
|
||||
final refreshResult = await authService!.refreshAccessToken();
|
||||
return refreshResult.when(
|
||||
success: (token) => uploadFile(
|
||||
endpoint: endpoint,
|
||||
filePath: filePath,
|
||||
fieldName: fieldName,
|
||||
additionalFields: additionalFields,
|
||||
isRetry: true,
|
||||
),
|
||||
onError: (error) {
|
||||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||
return Result.success(responseBody);
|
||||
} else {
|
||||
return _parseErrorFromString(responseBody, response.statusCode);
|
||||
}
|
||||
},
|
||||
cancelled: () {
|
||||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||
return Result.success(responseBody);
|
||||
} else {
|
||||
return _parseErrorFromString(responseBody, response.statusCode);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||
return Result.success(responseBody);
|
||||
} else {
|
||||
@@ -195,12 +301,21 @@ class CqrsApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, String> _buildHeaders() {
|
||||
Future<Map<String, String>> _buildHeaders() async {
|
||||
final headers = <String, String>{
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
...config.defaultHeaders,
|
||||
};
|
||||
|
||||
if (authService != null) {
|
||||
// Proactively ensure token is valid and refresh if needed
|
||||
final token = await authService!.ensureValidToken();
|
||||
if (token != null) {
|
||||
headers['Authorization'] = 'Bearer $token';
|
||||
}
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user