Files
fin-tracker/app/packages/api_client/lib/src/deserialize.dart
T
Dmitry baac83149f fix(api): Decimal-параметр ребалансировки ломал генерацию Dart-клиента
cash_available был bare Decimal | None в Query(...) — pydantic отдаёт для
Decimal anyOf[number, pattern-string], который openapi-generator не умеет
свернуть в один тип и вместо этого синтезирует пустой класс CashAvailable
без полей (синтаксически битый .dart, компиляция всего пакета падает).
Остальные Decimal-поля в API давно оборачиваются в Money/MoneyOpt
(api/schemas/common.py) ровно за счёт этого — anyOf[string, null] генератор
понимает. cash_available обошёл соглашение, потому что это единственный
Decimal-параметр запроса во всём API, а не тело ответа.
2026-09-19 10:56:33 +03:00

345 lines
18 KiB
Dart

import 'package:fintracker_api/src/model/account_balance.dart';
import 'package:fintracker_api/src/model/account_out.dart';
import 'package:fintracker_api/src/model/account_patch.dart';
import 'package:fintracker_api/src/model/account_suggestion.dart';
import 'package:fintracker_api/src/model/allocation_bucket.dart';
import 'package:fintracker_api/src/model/benchmark_comparison.dart';
import 'package:fintracker_api/src/model/benchmark_comparison_out.dart';
import 'package:fintracker_api/src/model/benchmark_create.dart';
import 'package:fintracker_api/src/model/benchmark_out.dart';
import 'package:fintracker_api/src/model/benchmark_patch.dart';
import 'package:fintracker_api/src/model/benchmark_return_out.dart';
import 'package:fintracker_api/src/model/calendar_entry.dart';
import 'package:fintracker_api/src/model/calendar_out.dart';
import 'package:fintracker_api/src/model/cash_flow_broker_month.dart';
import 'package:fintracker_api/src/model/cash_flow_month.dart';
import 'package:fintracker_api/src/model/category_out.dart';
import 'package:fintracker_api/src/model/commit_request.dart';
import 'package:fintracker_api/src/model/data_quality_row.dart';
import 'package:fintracker_api/src/model/event_out.dart';
import 'package:fintracker_api/src/model/event_page.dart';
import 'package:fintracker_api/src/model/forecast_month.dart';
import 'package:fintracker_api/src/model/forecast_out.dart';
import 'package:fintracker_api/src/model/goal_create.dart';
import 'package:fintracker_api/src/model/goal_out.dart';
import 'package:fintracker_api/src/model/goal_patch.dart';
import 'package:fintracker_api/src/model/goal_progress_out.dart';
import 'package:fintracker_api/src/model/health.dart';
import 'package:fintracker_api/src/model/history_out.dart';
import 'package:fintracker_api/src/model/history_row.dart';
import 'package:fintracker_api/src/model/history_totals.dart';
import 'package:fintracker_api/src/model/holding_out.dart';
import 'package:fintracker_api/src/model/import_counts.dart';
import 'package:fintracker_api/src/model/import_preview.dart';
import 'package:fintracker_api/src/model/import_result.dart';
import 'package:fintracker_api/src/model/import_summary.dart';
import 'package:fintracker_api/src/model/instrument_detail.dart';
import 'package:fintracker_api/src/model/instrument_out.dart';
import 'package:fintracker_api/src/model/link_create.dart';
import 'package:fintracker_api/src/model/link_out.dart';
import 'package:fintracker_api/src/model/login_request.dart';
import 'package:fintracker_api/src/model/lot_out.dart';
import 'package:fintracker_api/src/model/net_worth_breakdown.dart';
import 'package:fintracker_api/src/model/net_worth_day.dart';
import 'package:fintracker_api/src/model/new_instrument.dart';
import 'package:fintracker_api/src/model/pending_instrument_out.dart';
import 'package:fintracker_api/src/model/pending_resolve_request.dart';
import 'package:fintracker_api/src/model/pending_resolve_result.dart';
import 'package:fintracker_api/src/model/price_manual_in.dart';
import 'package:fintracker_api/src/model/price_manual_out.dart';
import 'package:fintracker_api/src/model/price_point.dart';
import 'package:fintracker_api/src/model/problem.dart';
import 'package:fintracker_api/src/model/rebalance_bucket_out.dart';
import 'package:fintracker_api/src/model/rebalance_out.dart';
import 'package:fintracker_api/src/model/reconciliation_cash.dart';
import 'package:fintracker_api/src/model/reconciliation_out.dart';
import 'package:fintracker_api/src/model/reconciliation_position.dart';
import 'package:fintracker_api/src/model/refresh_log_out.dart';
import 'package:fintracker_api/src/model/refresh_request.dart';
import 'package:fintracker_api/src/model/returns_out.dart';
import 'package:fintracker_api/src/model/rule_create.dart';
import 'package:fintracker_api/src/model/rule_out.dart';
import 'package:fintracker_api/src/model/rule_patch.dart';
import 'package:fintracker_api/src/model/runway_out.dart';
import 'package:fintracker_api/src/model/sample_event_out.dart';
import 'package:fintracker_api/src/model/scope_out.dart';
import 'package:fintracker_api/src/model/source_status.dart';
import 'package:fintracker_api/src/model/spending_row.dart';
import 'package:fintracker_api/src/model/summary_out.dart';
import 'package:fintracker_api/src/model/sync_job_out.dart';
import 'package:fintracker_api/src/model/sync_run_out.dart';
import 'package:fintracker_api/src/model/target_in.dart';
import 'package:fintracker_api/src/model/target_out.dart';
import 'package:fintracker_api/src/model/targets_in.dart';
import 'package:fintracker_api/src/model/targets_out.dart';
import 'package:fintracker_api/src/model/tax_account_out.dart';
import 'package:fintracker_api/src/model/tax_lot_out.dart';
import 'package:fintracker_api/src/model/tax_lots_out.dart';
import 'package:fintracker_api/src/model/tax_totals.dart';
import 'package:fintracker_api/src/model/tax_year_out.dart';
import 'package:fintracker_api/src/model/token_pair.dart';
import 'package:fintracker_api/src/model/trade_out.dart';
import 'package:fintracker_api/src/model/transaction_out.dart';
import 'package:fintracker_api/src/model/transaction_page.dart';
import 'package:fintracker_api/src/model/unmatched_broker_out.dart';
import 'package:fintracker_api/src/model/unmatched_out.dart';
import 'package:fintracker_api/src/model/unmatched_zm_out.dart';
import 'package:fintracker_api/src/model/user_out.dart';
import 'package:fintracker_api/src/model/value_day.dart';
final _regList = RegExp(r'^List<(.*)>$');
final _regSet = RegExp(r'^Set<(.*)>$');
final _regMap = RegExp(r'^Map<String,(.*)>$');
ReturnType deserialize<ReturnType, BaseType>(dynamic value, String targetType, {bool growable= true}) {
switch (targetType) {
case 'String':
return '$value' as ReturnType;
case 'int':
return (value is int ? value : int.parse('$value')) as ReturnType;
case 'bool':
if (value is bool) {
return value as ReturnType;
}
final valueString = '$value'.toLowerCase();
return (valueString == 'true' || valueString == '1') as ReturnType;
case 'double':
return (value is double ? value : double.parse('$value')) as ReturnType;
case 'AccountBalance':
return AccountBalance.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'AccountKind':
case 'AccountOut':
return AccountOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'AccountPatch':
return AccountPatch.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'AccountRole':
case 'AccountSuggestion':
return AccountSuggestion.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'AllocationBucket':
return AllocationBucket.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'AllocationDimension':
case 'BenchmarkComparison':
return BenchmarkComparison.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'BenchmarkComparisonOut':
return BenchmarkComparisonOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'BenchmarkCreate':
return BenchmarkCreate.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'BenchmarkOut':
return BenchmarkOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'BenchmarkPatch':
return BenchmarkPatch.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'BenchmarkReturnOut':
return BenchmarkReturnOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'Broker':
case 'CalendarEntry':
return CalendarEntry.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'CalendarOut':
return CalendarOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'CashFlowBrokerMonth':
return CashFlowBrokerMonth.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'CashFlowMonth':
return CashFlowMonth.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'CategoryOut':
return CategoryOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'CommitRequest':
return CommitRequest.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'DataQualityRow':
return DataQualityRow.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'EventKind':
case 'EventOut':
return EventOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'EventPage':
return EventPage.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'EventSource':
case 'EventStatus':
case 'FlowType':
case 'ForecastMonth':
return ForecastMonth.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'ForecastOut':
return ForecastOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'GoalCreate':
return GoalCreate.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'GoalOut':
return GoalOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'GoalPatch':
return GoalPatch.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'GoalProgressOut':
return GoalProgressOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'Health':
return Health.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'HistoryOut':
return HistoryOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'HistoryRow':
return HistoryRow.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'HistoryTotals':
return HistoryTotals.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'HoldingOut':
return HoldingOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'ImportCounts':
return ImportCounts.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'ImportPreview':
return ImportPreview.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'ImportResult':
return ImportResult.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'ImportSummary':
return ImportSummary.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'InstrumentDetail':
return InstrumentDetail.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'InstrumentOut':
return InstrumentOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'JobStatus':
case 'LinkCreate':
return LinkCreate.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'LinkOut':
return LinkOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'LoginRequest':
return LoginRequest.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'LotOut':
return LotOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'NetWorthBreakdown':
return NetWorthBreakdown.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'NetWorthDay':
return NetWorthDay.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'NewInstrument':
return NewInstrument.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'PendingInstrumentOut':
return PendingInstrumentOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'PendingResolveRequest':
return PendingResolveRequest.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'PendingResolveResult':
return PendingResolveResult.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'PriceManualIn':
return PriceManualIn.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'PriceManualOut':
return PriceManualOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'PricePoint':
return PricePoint.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'Problem':
return Problem.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'RebalanceBucketOut':
return RebalanceBucketOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'RebalanceOut':
return RebalanceOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'ReconciliationCash':
return ReconciliationCash.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'ReconciliationOut':
return ReconciliationOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'ReconciliationPosition':
return ReconciliationPosition.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'RefreshLogOut':
return RefreshLogOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'RefreshRequest':
return RefreshRequest.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'ReturnsOut':
return ReturnsOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'RuleCreate':
return RuleCreate.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'RuleKind':
case 'RuleMatchType':
case 'RuleOut':
return RuleOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'RulePatch':
return RulePatch.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'RunStatus':
case 'RunwayOut':
return RunwayOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'SampleEventOut':
return SampleEventOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'ScopeOut':
return ScopeOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'SourceStatus':
return SourceStatus.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'SpendingRow':
return SpendingRow.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'SummaryOut':
return SummaryOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'SyncJobOut':
return SyncJobOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'SyncRunOut':
return SyncRunOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'TargetIn':
return TargetIn.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'TargetOut':
return TargetOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'TargetsIn':
return TargetsIn.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'TargetsOut':
return TargetsOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'TaxAccountOut':
return TaxAccountOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'TaxLotOut':
return TaxLotOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'TaxLotsOut':
return TaxLotsOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'TaxTotals':
return TaxTotals.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'TaxYearOut':
return TaxYearOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'TokenPair':
return TokenPair.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'TradeOut':
return TradeOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'TransactionOut':
return TransactionOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'TransactionPage':
return TransactionPage.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'UnmatchedBrokerOut':
return UnmatchedBrokerOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'UnmatchedOut':
return UnmatchedOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'UnmatchedZmOut':
return UnmatchedZmOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'UserOut':
return UserOut.fromJson(value as Map<String, dynamic>) as ReturnType;
case 'ValueDay':
return ValueDay.fromJson(value as Map<String, dynamic>) as ReturnType;
default:
RegExpMatch? match;
if (value is List && (match = _regList.firstMatch(targetType)) != null) {
targetType = match![1]!; // ignore: parameter_assignments
return value
.map<BaseType>((dynamic v) => deserialize<BaseType, BaseType>(v, targetType, growable: growable))
.toList(growable: growable) as ReturnType;
}
if (value is Set && (match = _regSet.firstMatch(targetType)) != null) {
targetType = match![1]!; // ignore: parameter_assignments
return value
.map<BaseType>((dynamic v) => deserialize<BaseType, BaseType>(v, targetType, growable: growable))
.toSet() as ReturnType;
}
if (value is Map && (match = _regMap.firstMatch(targetType)) != null) {
targetType = match![1]!.trim(); // ignore: parameter_assignments
return Map<String, BaseType>.fromIterables(
value.keys as Iterable<String>,
value.values.map((dynamic v) => deserialize<BaseType, BaseType>(v, targetType, growable: growable)),
) as ReturnType;
}
break;
}
throw Exception('Cannot deserialize');
}